diff --git a/scripts/dh_speed.c b/scripts/dh_speed.c index 11e77bef6..0046dd10f 100644 --- a/scripts/dh_speed.c +++ b/scripts/dh_speed.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include static void usage() { @@ -29,7 +29,7 @@ static void usage() struct { char *name; - diffie_hellman_group_t group; + key_exchange_method_t group; } groups[] = { {"modp768", MODP_768_BIT}, {"modp1024", MODP_1024_BIT}, @@ -65,43 +65,43 @@ static double end_timing(struct timespec *start) (end.tv_sec - start->tv_sec) * 1.0; } -static void run_test(diffie_hellman_group_t group, int rounds) +static void run_test(key_exchange_method_t group, int rounds) { - diffie_hellman_t *l[rounds], *r; + key_exchange_t *l[rounds], *r; chunk_t chunk, chunks[rounds], lsecrets[rounds], rsecrets[rounds]; struct timespec timing; int round; - r = lib->crypto->create_dh(lib->crypto, group); + r = lib->crypto->create_ke(lib->crypto, group); if (!r) { - printf("skipping %N, not supported\n", - diffie_hellman_group_names, group); + printf("skipping %N, not supported\n", key_exchange_method_names, + group); return; } - printf("%N:\t", diffie_hellman_group_names, group); + printf("%N:\t", key_exchange_method_names, group); start_timing(&timing); for (round = 0; round < rounds; round++) { - l[round] = lib->crypto->create_dh(lib->crypto, group); - assert(l[round]->get_my_public_value(l[round], &chunks[round])); + l[round] = lib->crypto->create_ke(lib->crypto, group); + assert(l[round]->get_public_key(l[round], &chunks[round])); } printf("A = g^a/s: %8.1f", rounds / end_timing(&timing)); for (round = 0; round < rounds; round++) { - assert(r->set_other_public_value(r, chunks[round])); + assert(r->set_public_key(r, chunks[round])); assert(r->get_shared_secret(r, &rsecrets[round])); chunk_free(&chunks[round]); } - assert(r->get_my_public_value(r, &chunk)); + assert(r->get_public_key(r, &chunk)); start_timing(&timing); for (round = 0; round < rounds; round++) { - assert(l[round]->set_other_public_value(l[round], chunk)); + assert(l[round]->set_public_key(l[round], chunk)); assert(l[round]->get_shared_secret(l[round], &lsecrets[round])); } printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing)); diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c index ec2ca46ad..2b2d103d0 100644 --- a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c +++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c @@ -40,12 +40,12 @@ struct private_tkm_diffie_hellman_t { tkm_diffie_hellman_t public; /** - * Diffie Hellman group number. + * Diffie-Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** - * Diffie Hellman public value. + * Diffie-Hellman public value. */ dh_pubvalue_type pubvalue; @@ -56,14 +56,14 @@ struct private_tkm_diffie_hellman_t { }; -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_tkm_diffie_hellman_t *this, chunk_t *value) { sequence_to_chunk(this->pubvalue.data, this->pubvalue.size, value); return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_tkm_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_empty; @@ -71,7 +71,7 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_tkm_diffie_hellman_t *this, chunk_t value) { dh_pubvalue_type othervalue; @@ -81,13 +81,13 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, return ike_dh_generate_key(this->context_id, othervalue) == TKM_OK; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_tkm_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_tkm_diffie_hellman_t *this) { if (ike_dh_reset(this->context_id) != TKM_OK) @@ -107,13 +107,13 @@ METHOD(tkm_diffie_hellman_t, get_id, dh_id_type, static u_int hash(void *key) { - diffie_hellman_group_t k = *(diffie_hellman_group_t*)key; + key_exchange_method_t k = *(key_exchange_method_t*)key; return chunk_hash(chunk_from_thing(k)); } static bool equals(void *key, void *other_key) { - return *(diffie_hellman_group_t*)key == *(diffie_hellman_group_t*)other_key; + return *(key_exchange_method_t*)key == *(key_exchange_method_t*)other_key; } /* @@ -123,7 +123,7 @@ int register_dh_mapping() { int count, i; char *iana_id_str, *tkm_id_str; - diffie_hellman_group_t *iana_id; + key_exchange_method_t *iana_id; uint64_t *tkm_id; hashtable_t *map; enumerator_t *enumerator; @@ -137,7 +137,7 @@ int register_dh_mapping() while (enumerator->enumerate(enumerator, &iana_id_str, &tkm_id_str)) { - iana_id = malloc_thing(diffie_hellman_group_t); + iana_id = malloc_thing(key_exchange_method_t); *iana_id = settings_value_as_int(iana_id_str, 0); tkm_id = malloc_thing(uint64_t); *tkm_id = settings_value_as_int(tkm_id_str, 0); @@ -148,13 +148,13 @@ int register_dh_mapping() count = map->get_count(map); plugin_feature_t f[count + 1]; - f[0] = PLUGIN_REGISTER(DH, tkm_diffie_hellman_create); + f[0] = PLUGIN_REGISTER(KE, tkm_diffie_hellman_create); i = 1; enumerator = map->create_enumerator(map); while (enumerator->enumerate(enumerator, &iana_id, &tkm_id)) { - f[i] = PLUGIN_PROVIDE(DH, *iana_id); + f[i] = PLUGIN_PROVIDE(KE, *iana_id); i++; } enumerator->destroy(enumerator); @@ -198,7 +198,7 @@ void destroy_dh_mapping() /* * Described in header. */ -tkm_diffie_hellman_t *tkm_diffie_hellman_create(diffie_hellman_group_t group) +tkm_diffie_hellman_t *tkm_diffie_hellman_create(key_exchange_method_t group) { private_tkm_diffie_hellman_t *this; @@ -209,11 +209,11 @@ tkm_diffie_hellman_t *tkm_diffie_hellman_create(diffie_hellman_group_t group) INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .get_method = _get_method, .destroy = _destroy, }, .get_id = _get_id, diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.h b/src/charon-tkm/src/tkm/tkm_diffie_hellman.h index e3761c9d0..c6999efb8 100644 --- a/src/charon-tkm/src/tkm/tkm_diffie_hellman.h +++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.h @@ -29,14 +29,14 @@ typedef struct tkm_diffie_hellman_t tkm_diffie_hellman_t; #include /** - * diffie_hellman_t implementation using the trusted key manager. + * key_exchange_t implementation using the trusted key manager. */ struct tkm_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; /** * Get Diffie-Hellman context id. @@ -66,6 +66,6 @@ void destroy_dh_mapping(); * @param group Diffie Hellman group number to use * @return tkm_diffie_hellman_t object, NULL if not supported */ -tkm_diffie_hellman_t *tkm_diffie_hellman_create(diffie_hellman_group_t group); +tkm_diffie_hellman_t *tkm_diffie_hellman_create(key_exchange_method_t group); #endif /** TKM_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c index ad56cead0..6e79c639e 100644 --- a/src/charon-tkm/src/tkm/tkm_keymat.c +++ b/src/charon-tkm/src/tkm/tkm_keymat.c @@ -82,10 +82,10 @@ METHOD(keymat_t, get_version, ike_version_t, return IKEV2; } -METHOD(keymat_t, create_dh, diffie_hellman_t*, - private_tkm_keymat_t *this, diffie_hellman_group_t group) +METHOD(keymat_t, create_ke, key_exchange_t*, + private_tkm_keymat_t *this, key_exchange_method_t ke) { - return lib->crypto->create_dh(lib->crypto, group); + return lib->crypto->create_ke(lib->crypto, ke); } METHOD(keymat_t, create_nonce_gen, nonce_gen_t*, @@ -95,7 +95,7 @@ METHOD(keymat_t, create_nonce_gen, nonce_gen_t*, } METHOD(keymat_v2_t, derive_ike_keys, bool, - private_tkm_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh, + private_tkm_keymat_t *this, proposal_t *proposal, key_exchange_t *ke, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, pseudo_random_function_t rekey_function, chunk_t rekey_skd) { @@ -119,7 +119,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, } /* Get DH context id */ - tkm_dh = (tkm_diffie_hellman_t *)dh; + tkm_dh = (tkm_diffie_hellman_t *)ke; dh_id = tkm_dh->get_id(tkm_dh); if (this->initiator) @@ -198,16 +198,16 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, } METHOD(keymat_v2_t, derive_child_keys, bool, - private_tkm_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh, + private_tkm_keymat_t *this, proposal_t *proposal, key_exchange_t *ke, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r) { esa_info_t *esa_info_i, *esa_info_r; dh_id_type dh_id = 0; - if (dh) + if (ke) { - dh_id = ((tkm_diffie_hellman_t *)dh)->get_id((tkm_diffie_hellman_t *)dh); + dh_id = ((tkm_diffie_hellman_t *)ke)->get_id((tkm_diffie_hellman_t *)ke); } INIT(esa_info_i, @@ -379,7 +379,7 @@ tkm_keymat_t *tkm_keymat_create(bool initiator) .keymat_v2 = { .keymat = { .get_version = _get_version, - .create_dh = _create_dh, + .create_ke = _create_ke, .create_nonce_gen = _create_nonce_gen, .get_aead = _get_aead, .destroy = _destroy, diff --git a/src/charon-tkm/tests/diffie_hellman_tests.c b/src/charon-tkm/tests/diffie_hellman_tests.c index 7e971b885..e3d42ef0f 100644 --- a/src/charon-tkm/tests/diffie_hellman_tests.c +++ b/src/charon-tkm/tests/diffie_hellman_tests.c @@ -31,7 +31,7 @@ START_TEST(test_dh_creation) fail_if(!dh, "MODP_4096 not created"); fail_if(!dh->get_id(dh), "Invalid context id (0)"); - dh->dh.destroy(&dh->dh); + dh->ke.destroy(&dh->ke); } END_TEST @@ -41,8 +41,8 @@ START_TEST(test_dh_get_my_pubvalue) fail_if(!dh, "Unable to create DH"); chunk_t value; - ck_assert(dh->dh.get_my_public_value(&dh->dh, &value)); - dh->dh.destroy(&dh->dh); + ck_assert(dh->ke.get_public_key(&dh->ke, &value)); + dh->ke.destroy(&dh->ke); fail_if(value.ptr == NULL, "Pubvalue is NULL"); fail_if(value.len != 512, "Pubvalue size mismatch"); diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c index d3e4af6a1..e5d6280e7 100644 --- a/src/charon-tkm/tests/keymat_tests.c +++ b/src/charon-tkm/tests/keymat_tests.c @@ -52,11 +52,11 @@ START_TEST(test_derive_ike_keys) /* Use the same pubvalue for both sides */ chunk_t pubvalue; - ck_assert(dh->dh.get_my_public_value(&dh->dh, &pubvalue)); - ck_assert(dh->dh.set_other_public_value(&dh->dh, pubvalue)); + ck_assert(dh->ke.get_public_key(&dh->ke, &pubvalue)); + ck_assert(dh->ke.set_public_key(&dh->ke, pubvalue)); fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal, - &dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty), + &dh->ke, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty), "Key derivation failed"); chunk_free(&nonce); @@ -70,7 +70,7 @@ START_TEST(test_derive_ike_keys) ng->nonce_gen.destroy(&ng->nonce_gen); proposal->destroy(proposal); - dh->dh.destroy(&dh->dh); + dh->ke.destroy(&dh->ke); ike_sa_id->destroy(ike_sa_id); keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat); chunk_free(&pubvalue); @@ -93,7 +93,7 @@ START_TEST(test_derive_child_keys) chunk_t nonce = chunk_from_chars("test chunk"); fail_unless(keymat->keymat_v2.derive_child_keys(&keymat->keymat_v2, proposal, - (diffie_hellman_t *)dh, + &dh->ke, nonce, nonce, &encr_i, &integ_i, &encr_r, &integ_r), "Child key derivation failed"); @@ -133,7 +133,7 @@ START_TEST(test_derive_child_keys) chunk_free(&info->nonce_r); proposal->destroy(proposal); - dh->dh.destroy(&dh->dh); + dh->ke.destroy(&dh->ke); keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat); chunk_free(&encr_i); chunk_free(&encr_r); diff --git a/src/conftest/hooks/log_ke.c b/src/conftest/hooks/log_ke.c index 02bf7e307..766686dd3 100644 --- a/src/conftest/hooks/log_ke.c +++ b/src/conftest/hooks/log_ke.c @@ -48,7 +48,7 @@ METHOD(listener_t, message, bool, { ke = (ke_payload_t*)payload; DBG1(DBG_CFG, "received DH group %N", - diffie_hellman_group_names, ke->get_dh_group_number(ke)); + key_exchange_method_names, ke->get_key_exchange_method(ke)); } } enumerator->destroy(enumerator); diff --git a/src/conftest/hooks/set_proposal_number.c b/src/conftest/hooks/set_proposal_number.c index fdd36a1ce..4d059653d 100644 --- a/src/conftest/hooks/set_proposal_number.c +++ b/src/conftest/hooks/set_proposal_number.c @@ -110,7 +110,7 @@ METHOD(listener_t, message, bool, copy_proposal_algs(proposal, new, ENCRYPTION_ALGORITHM); copy_proposal_algs(proposal, new, INTEGRITY_ALGORITHM); copy_proposal_algs(proposal, new, PSEUDO_RANDOM_FUNCTION); - copy_proposal_algs(proposal, new, DIFFIE_HELLMAN_GROUP); + copy_proposal_algs(proposal, new, KEY_EXCHANGE_METHOD); copy_proposal_algs(proposal, new, EXTENDED_SEQUENCE_NUMBERS); updated->insert_last(updated, new); } diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index 59c666447..57eaaac89 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -574,7 +574,7 @@ METHOD(bus_t, message, void, } METHOD(bus_t, ike_keys, void, - private_bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, + private_bus_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method) { @@ -639,7 +639,7 @@ METHOD(bus_t, ike_derived_keys, void, METHOD(bus_t, child_keys, void, private_bus_t *this, child_sa_t *child_sa, bool initiator, - diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r) + key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r) { enumerator_t *enumerator; ike_sa_t *ike_sa; diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index 4be894d23..5e809f04f 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -356,7 +356,7 @@ struct bus_t { * @param shared shared key used for key derivation (IKEv1-PSK only) * @param method auth method for key derivation (IKEv1-non-PSK only) */ - void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, + void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method); @@ -386,7 +386,7 @@ struct bus_t { * @param nonce_r responder's nonce */ void (*child_keys)(bus_t *this, child_sa_t *child_sa, bool initiator, - diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r); + key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r); /** * CHILD_SA derived keys hook. diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index 2832a81db..bec48d187 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -92,7 +92,7 @@ struct listener_t { * @param method auth method for key derivation (IKEv1-non-PSK only) * @return TRUE to stay registered, FALSE to unregister */ - bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, + bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method); @@ -125,7 +125,7 @@ struct listener_t { * @return TRUE to stay registered, FALSE to unregister */ bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r); /** diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index c8d4b4cf2..78d1f3c43 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -216,16 +216,16 @@ CALLBACK(match_proposal, bool, } METHOD(child_cfg_t, get_proposals, linked_list_t*, - private_child_cfg_t *this, bool strip_dh) + private_child_cfg_t *this, bool strip_ke) { enumerator_t *enumerator; proposal_t *current; proposal_selection_flag_t flags = 0; linked_list_t *proposals = linked_list_create(); - if (strip_dh) + if (strip_ke) { - flags |= PROPOSAL_SKIP_DH; + flags |= PROPOSAL_SKIP_KE; } enumerator = this->proposals->create_enumerator(this->proposals); @@ -484,23 +484,23 @@ METHOD(child_cfg_t, get_close_action, action_t, return this->close_action; } -METHOD(child_cfg_t, get_dh_group, diffie_hellman_group_t, - private_child_cfg_t *this) +METHOD(child_cfg_t, get_algorithm, uint16_t, + private_child_cfg_t *this, transform_type_t type) { enumerator_t *enumerator; proposal_t *proposal; - uint16_t dh_group = MODP_NONE; + uint16_t alg = 0; enumerator = this->proposals->create_enumerator(this->proposals); while (enumerator->enumerate(enumerator, &proposal)) { - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL)) + if (proposal->get_algorithm(proposal, type, &alg, NULL)) { break; } } enumerator->destroy(enumerator); - return dh_group; + return alg; } METHOD(child_cfg_t, get_inactivity, uint32_t, @@ -758,7 +758,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data) .get_dpd_action = _get_dpd_action, .get_close_action = _get_close_action, .get_lifetime = _get_lifetime, - .get_dh_group = _get_dh_group, + .get_algorithm = _get_algorithm, .get_inactivity = _get_inactivity, .get_reqid = _get_reqid, .get_if_id = _get_if_id, diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index 8e7c2558c..9c4425275 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -89,10 +89,10 @@ struct child_cfg_t { * * Resulting list and all of its proposals must be freed after use. * - * @param strip_dh TRUE strip out diffie hellman groups + * @param strip_ke TRUE strip out key exchange methods * @return list of proposals */ - linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_dh); + linked_list_t* (*get_proposals)(child_cfg_t *this, bool strip_ke); /** * Select a proposal from a supplied list. @@ -204,11 +204,16 @@ struct child_cfg_t { action_t (*get_close_action) (child_cfg_t *this); /** - * Get the DH group to use for CHILD_SA setup. + * Get the first algorithm of a certain transform type that's contained in + * any of the configured proposals. * - * @return dh group to use + * For instance, use with KEY_EXCHANGE_METHOD to get the KE method to use + * for the CHILD_SA initiation. + * + * @param type transform type to look for + * @return algorithm identifier (0 for none) */ - diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this); + uint16_t (*get_algorithm)(child_cfg_t *this, transform_type_t type); /** * Get the inactivity timeout value. diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index a2cc7d6ad..792f8022a 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -348,23 +348,23 @@ METHOD(ike_cfg_t, select_proposal, proposal_t*, return proposal_select(this->proposals, proposals, flags); } -METHOD(ike_cfg_t, get_dh_group, diffie_hellman_group_t, - private_ike_cfg_t *this) +METHOD(ike_cfg_t, get_algorithm, uint16_t, + private_ike_cfg_t *this, transform_type_t type) { enumerator_t *enumerator; proposal_t *proposal; - uint16_t dh_group = MODP_NONE; + uint16_t alg = 0; enumerator = this->proposals->create_enumerator(this->proposals); while (enumerator->enumerate(enumerator, &proposal)) { - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL)) + if (proposal->get_algorithm(proposal, type, &alg, NULL)) { break; } } enumerator->destroy(enumerator); - return dh_group; + return alg; } METHOD(ike_cfg_t, equals, bool, @@ -603,7 +603,7 @@ ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data) .get_proposals = _get_proposals, .select_proposal = _select_proposal, .has_proposal = _has_proposal, - .get_dh_group = _get_dh_group, + .get_algorithm = _get_algorithm, .equals = _equals, .get_ref = _get_ref, .destroy = _destroy, diff --git a/src/libcharon/config/ike_cfg.h b/src/libcharon/config/ike_cfg.h index 601f2a021..0b4fe356f 100644 --- a/src/libcharon/config/ike_cfg.h +++ b/src/libcharon/config/ike_cfg.h @@ -35,7 +35,6 @@ typedef struct ike_cfg_create_t ike_cfg_create_t; #include #include #include -#include /** * IKE version. @@ -231,11 +230,16 @@ struct ike_cfg_t { childless_t (*childless)(ike_cfg_t *this); /** - * Get the DH group to use for IKE_SA setup. + * Get the first algorithm of a certain transform type that's contained in + * any of the configured proposals. * - * @return dh group to use for initialization + * For instance, use with KEY_EXCHANGE_METHOD to get the KE metho to use + * for the IKE_SA initiation. + * + * @param type transform type to look for + * @return algorithm identifier (0 for none) */ - diffie_hellman_group_t (*get_dh_group)(ike_cfg_t *this); + uint16_t (*get_algorithm)(ike_cfg_t *this, transform_type_t type); /** * Check if two IKE configs are equal. diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index db51aa714..5156436f8 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -1565,7 +1565,7 @@ static encrypted_payload_t* wrap_payloads(private_message_t *this) } } if (encrypted) - { /* simply adopt all the unencrypted payloads */ + { /* simply adopt all the unprotected payloads */ this->payloads->destroy(this->payloads); this->payloads = payloads; return encrypted; @@ -1655,7 +1655,7 @@ static ike_header_t *create_header(private_message_t *this) * * The generator and the possible encrypted payload are returned. The latter * is not yet encrypted (but the transform is set). It is also not added to - * the payload list (so unless there are unencrypted payloads that list will + * the payload list (so unless there are unprotected payloads that list will * be empty afterwards). */ static status_t generate_message(private_message_t *this, keymat_t *keymat, @@ -1943,7 +1943,7 @@ static message_t *create_fragment(private_message_t *this, payload_type_t next, /* only in the first fragment is this set to the type of the first * payload in the encrypted payload */ fragment->set_next_type(fragment, next); - /* move unencrypted payloads to the first fragment */ + /* move unprotected payloads to the first fragment */ enumerator = this->payloads->create_enumerator(this->payloads); while (enumerator->enumerate(enumerator, &payload)) { @@ -2096,7 +2096,7 @@ METHOD(message_t, fragment, status_t, /* padding and padding length */ frag_len = round_down(frag_len, aead->get_block_size(aead)); REDUCE_FRAG_LEN(frag_len, 1); - /* TODO-FRAG: if there are unencrypted payloads, should we account for + /* TODO-FRAG: if there are unprotected payloads, should we account for * their length in the first fragment? we still would have to add * an encrypted fragment payload (albeit empty), even so we couldn't * prevent IP fragmentation in every case */ @@ -2894,7 +2894,7 @@ METHOD(message_t, add_fragment_v2, status_t, /* the first fragment denotes the payload type of the first payload in * the original encrypted payload, cache that */ this->first_payload = payload->get_next_type(payload); - /* move all unencrypted payloads contained in the first fragment */ + /* move all unprotected payloads contained in the first fragment */ enumerator = message->create_payload_enumerator(message); while (enumerator->enumerate(enumerator, &payload)) { @@ -2920,10 +2920,18 @@ METHOD(message_t, add_fragment_v2, status_t, data = merge_fragments(this, message); + /* use the cached next payload type from the SKF of the first fragment */ encrypted = encrypted_payload_create_from_plain(this->first_payload, data); encrypted->set_transform(encrypted, aead); + + if (this->payloads->get_last(this->payloads, (void**)&payload) == SUCCESS) + { /* if there are any unprotected payloads, update the last one's next + * payload type (it points to an SKF instead of an SK) */ + payload->set_next_type(payload, encrypted->payload_interface.get_type( + &encrypted->payload_interface)); + } this->payloads->insert_last(this->payloads, encrypted); - /* update next payload type (could be an unencrypted payload) */ + /* update payload type in the header (could be an unprotected payload) */ this->payloads->get_first(this->payloads, (void**)&payload); this->first_payload = payload->get_type(payload); diff --git a/src/libcharon/encoding/payloads/ke_payload.c b/src/libcharon/encoding/payloads/ke_payload.c index 610042a8d..565654dd3 100644 --- a/src/libcharon/encoding/payloads/ke_payload.c +++ b/src/libcharon/encoding/payloads/ke_payload.c @@ -59,9 +59,9 @@ struct private_ke_payload_t { uint16_t payload_length; /** - * DH Group Number. + * Key exchange method number. */ - uint16_t dh_group_number; + uint16_t ke_method; /** * Key Exchange Data of this KE payload. @@ -92,8 +92,8 @@ static encoding_rule_t encodings_v2[] = { { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[6]) }, /* Length of the whole payload*/ { PAYLOAD_LENGTH, offsetof(private_ke_payload_t, payload_length) }, - /* DH Group number as 16 bit field*/ - { U_INT_16, offsetof(private_ke_payload_t, dh_group_number) }, + /* Key exchange method number as 16 bit field*/ + { U_INT_16, offsetof(private_ke_payload_t, ke_method) }, /* 2 reserved bytes */ { RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[0])}, { RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[1])}, @@ -107,7 +107,7 @@ static encoding_rule_t encodings_v2[] = { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! Next Payload !C! RESERVED ! Payload Length ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ! DH Group # ! RESERVED ! + ! KE method # ! RESERVED ! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! ! ~ Key Exchange Data ~ @@ -197,10 +197,10 @@ METHOD(ke_payload_t, get_key_exchange_data, chunk_t, return this->key_exchange_data; } -METHOD(ke_payload_t, get_dh_group_number, diffie_hellman_group_t, +METHOD(ke_payload_t, get_key_exchange_method, key_exchange_method_t, private_ke_payload_t *this) { - return this->dh_group_number; + return this->ke_method; } METHOD2(payload_t, ke_payload_t, destroy, void, @@ -230,11 +230,11 @@ ke_payload_t *ke_payload_create(payload_type_t type) .destroy = _destroy, }, .get_key_exchange_data = _get_key_exchange_data, - .get_dh_group_number = _get_dh_group_number, + .get_key_exchange_method = _get_key_exchange_method, .destroy = _destroy, }, .next_payload = PL_NONE, - .dh_group_number = MODP_NONE, + .ke_method = KE_NONE, .type = type, ); this->payload_length = get_header_length(this); @@ -244,19 +244,19 @@ ke_payload_t *ke_payload_create(payload_type_t type) /* * Described in header */ -ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type, - diffie_hellman_t *dh) +ke_payload_t *ke_payload_create_from_key_exchange(payload_type_t type, + key_exchange_t *ke) { private_ke_payload_t *this; chunk_t value; - if (!dh->get_my_public_value(dh, &value)) + if (!ke->get_public_key(ke, &value)) { return NULL; } this = (private_ke_payload_t*)ke_payload_create(type); this->key_exchange_data = value; - this->dh_group_number = dh->get_dh_group(dh); + this->ke_method = ke->get_method(ke); this->payload_length += this->key_exchange_data.len; return &this->public; diff --git a/src/libcharon/encoding/payloads/ke_payload.h b/src/libcharon/encoding/payloads/ke_payload.h index 4be039225..295c46c62 100644 --- a/src/libcharon/encoding/payloads/ke_payload.h +++ b/src/libcharon/encoding/payloads/ke_payload.h @@ -29,7 +29,7 @@ typedef struct ke_payload_t ke_payload_t; #include #include #include -#include +#include /** * Class representing an IKEv1 or IKEv2 key exchange payload. @@ -49,11 +49,11 @@ struct ke_payload_t { chunk_t (*get_key_exchange_data) (ke_payload_t *this); /** - * Gets the Diffie-Hellman Group Number of this KE payload (IKEv2 only). + * Gets the key exchange method of this KE payload (IKEv2 only). * - * @return DH Group Number of this payload + * @return key exchange method of this payload */ - diffie_hellman_group_t (*get_dh_group_number) (ke_payload_t *this); + key_exchange_method_t (*get_key_exchange_method)(ke_payload_t *this); /** * Destroys a ke_payload_t object. @@ -70,13 +70,13 @@ struct ke_payload_t { ke_payload_t *ke_payload_create(payload_type_t type); /** - * Creates a ke_payload_t from a diffie_hellman_t. + * Creates a ke_payload_t from a key_exchange_t. * * @param type PLV2_KEY_EXCHANGE or PLV1_KEY_EXCHANGE - * @param dh diffie hellman object containing group and key + * @param ke key exchange object containing method and public key * @return ke_payload_t object, NULL on error */ -ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type, - diffie_hellman_t *dh); +ke_payload_t *ke_payload_create_from_key_exchange(payload_type_t type, + key_exchange_t *ke); #endif /** KE_PAYLOAD_H_ @}*/ diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index e26a55c75..a1cd71093 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -904,7 +904,7 @@ static void add_to_proposal_v1_ike(proposal_t *proposal, get_alg_from_ikev1(PSEUDO_RANDOM_FUNCTION, value), 0); break; case TATTR_PH1_GROUP: - proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, value, 0); break; default: @@ -951,7 +951,7 @@ static void add_to_proposal_v1(proposal_t *proposal, get_alg_from_ikev1_auth(value), 0); break; case TATTR_PH2_GROUP: - proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, value, 0); break; case TATTR_PH2_EXT_SEQ_NUMBER: @@ -1318,7 +1318,7 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this, } enumerator->destroy(enumerator); - enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP); + enumerator = proposal->create_enumerator(proposal, KEY_EXCHANGE_METHOD); if (enumerator->enumerate(enumerator, &alg, &key_size)) { transform->add_transform_attribute(transform, @@ -1396,7 +1396,7 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this, return; } - enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP); + enumerator = proposal->create_enumerator(proposal, KEY_EXCHANGE_METHOD); if (enumerator->enumerate(enumerator, &alg, &key_size)) { transform->add_transform_attribute(transform, @@ -1489,11 +1489,11 @@ static void set_from_proposal_v2(private_proposal_substructure_t *this, enumerator->destroy(enumerator); /* dh groups */ - enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP); + enumerator = proposal->create_enumerator(proposal, KEY_EXCHANGE_METHOD); while (enumerator->enumerate(enumerator, &alg, NULL)) { transform = transform_substructure_create_type(PLV2_TRANSFORM_SUBSTRUCTURE, - DIFFIE_HELLMAN_GROUP, alg); + KEY_EXCHANGE_METHOD, alg); add_transform_substructure(this, transform); } enumerator->destroy(enumerator); diff --git a/src/libcharon/encoding/payloads/transform_substructure.h b/src/libcharon/encoding/payloads/transform_substructure.h index c732be55d..d2619b18e 100644 --- a/src/libcharon/encoding/payloads/transform_substructure.h +++ b/src/libcharon/encoding/payloads/transform_substructure.h @@ -29,7 +29,7 @@ typedef struct transform_substructure_t transform_substructure_t; #include #include #include -#include +#include #include #include #include diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c index 89615e74d..2485b49bb 100644 --- a/src/libcharon/plugins/ha/ha_child.c +++ b/src/libcharon/plugins/ha/ha_child.c @@ -51,7 +51,7 @@ struct private_ha_child_t { METHOD(listener_t, child_keys, bool, private_ha_child_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, - bool initiator, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r) + bool initiator, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r) { ha_message_t *m; chunk_t secret; @@ -92,7 +92,7 @@ METHOD(listener_t, child_keys, bool, { m->add_attribute(m, HA_ALG_INTEG, alg); } - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL)) + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL)) { m->add_attribute(m, HA_ALG_DH, alg); } diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index 3e1958749..3cf1aa671 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -67,9 +67,9 @@ struct private_ha_dispatcher_t { struct ha_diffie_hellman_t { /** - * Implements diffie_hellman_t + * Implements key_exchange_t */ - diffie_hellman_t dh; + key_exchange_t dh; /** * Shared secret @@ -82,21 +82,21 @@ struct ha_diffie_hellman_t { chunk_t pub; }; -METHOD(diffie_hellman_t, dh_get_shared_secret, bool, +METHOD(key_exchange_t, dh_get_shared_secret, bool, ha_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_clone(this->secret); return TRUE; } -METHOD(diffie_hellman_t, dh_get_my_public_value, bool, +METHOD(key_exchange_t, dh_get_public_key, bool, ha_diffie_hellman_t *this, chunk_t *value) { *value = chunk_clone(this->pub); return TRUE; } -METHOD(diffie_hellman_t, dh_destroy, void, +METHOD(key_exchange_t, dh_destroy, void, ha_diffie_hellman_t *this) { free(this); @@ -105,14 +105,14 @@ METHOD(diffie_hellman_t, dh_destroy, void, /** * Create a HA synced DH implementation */ -static diffie_hellman_t *ha_diffie_hellman_create(chunk_t secret, chunk_t pub) +static key_exchange_t *ha_diffie_hellman_create(chunk_t secret, chunk_t pub) { ha_diffie_hellman_t *this; INIT(this, .dh = { .get_shared_secret = _dh_get_shared_secret, - .get_my_public_value = _dh_get_my_public_value, + .get_public_key = _dh_get_public_key, .destroy = _dh_destroy, }, .secret = secret, @@ -210,7 +210,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message if (ike_sa) { proposal_t *proposal; - diffie_hellman_t *dh; + key_exchange_t *dh; proposal = proposal_create(PROTO_IKE, 0); if (integ) @@ -227,7 +227,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message } if (dh_grp) { - proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, dh_grp, 0); + proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, dh_grp, 0); } charon->bus->set_sa(charon->bus, ike_sa); dh = ha_diffie_hellman_create(secret, dh_local); @@ -662,7 +662,7 @@ static void process_child_add(private_ha_dispatcher_t *this, chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty; chunk_t encr_i, integ_i, encr_r, integ_r; linked_list_t *local_ts, *remote_ts; - diffie_hellman_t *dh = NULL; + key_exchange_t *dh = NULL; enumerator = message->create_attribute_enumerator(message); while (enumerator->enumerate(enumerator, &attribute, &value)) @@ -762,7 +762,7 @@ static void process_child_add(private_ha_dispatcher_t *this, } if (dh_grp) { - proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, dh_grp, 0); + proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, dh_grp, 0); } proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, esn, 0); if (secret.len) diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index ded9f3d2b..6535e4a1e 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -82,7 +82,7 @@ static void copy_extensions(ha_message_t *m, ike_sa_t *ike_sa) } METHOD(listener_t, ike_keys, bool, - private_ha_ike_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh, + private_ha_ike_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, shared_key_t *shared, auth_method_t method) { @@ -132,7 +132,7 @@ METHOD(listener_t, ike_keys, bool, { m->add_attribute(m, HA_ALG_PRF, alg); } - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL)) + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL)) { m->add_attribute(m, HA_ALG_DH, alg); } @@ -142,7 +142,7 @@ METHOD(listener_t, ike_keys, bool, chunk_clear(&secret); if (ike_sa->get_version(ike_sa) == IKEV1) { - if (dh->get_my_public_value(dh, &secret)) + if (dh->get_public_key(dh, &secret)) { m->add_attribute(m, HA_LOCAL_DH, secret); chunk_free(&secret); diff --git a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c index 1307db342..8b5630bf6 100644 --- a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c +++ b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c @@ -16,33 +16,33 @@ #include "load_tester_diffie_hellman.h" -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, load_tester_diffie_hellman_t *this, chunk_t *value) { *value = chunk_empty; return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, load_tester_diffie_hellman_t *this, chunk_t value) { return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, load_tester_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_empty; return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, load_tester_diffie_hellman_t *this) { return MODP_NULL; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, load_tester_diffie_hellman_t *this) { free(this); @@ -52,7 +52,7 @@ METHOD(diffie_hellman_t, destroy, void, * See header */ load_tester_diffie_hellman_t *load_tester_diffie_hellman_create( - diffie_hellman_group_t group) + key_exchange_method_t group) { load_tester_diffie_hellman_t *this; @@ -62,11 +62,11 @@ load_tester_diffie_hellman_t *load_tester_diffie_hellman_create( } INIT(this, - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .get_method = _get_method, .destroy = _destroy, } ); diff --git a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.h b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.h index d1a3ea898..d17a119eb 100644 --- a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.h +++ b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.h @@ -22,7 +22,7 @@ #ifndef LOAD_TESTER_DIFFIE_HELLMAN_H_ #define LOAD_TESTER_DIFFIE_HELLMAN_H_ -#include +#include typedef struct load_tester_diffie_hellman_t load_tester_diffie_hellman_t; @@ -32,18 +32,18 @@ typedef struct load_tester_diffie_hellman_t load_tester_diffie_hellman_t; struct load_tester_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** - * Creates a new gmp_diffie_hellman_t object. + * Creates a new load_tester_diffie_hellman_t object. * * @param group Diffie Hellman group, supports MODP_NULL only - * @return gmp_diffie_hellman_t object + * @return load_tester_diffie_hellman_t object */ load_tester_diffie_hellman_t *load_tester_diffie_hellman_create( - diffie_hellman_group_t group); + key_exchange_method_t group); #endif /** LOAD_TESTER_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c index 20eea42a4..db957f0e9 100644 --- a/src/libcharon/plugins/load_tester/load_tester_plugin.c +++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c @@ -231,8 +231,8 @@ METHOD(plugin_t, get_features, int, private_load_tester_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { - PLUGIN_REGISTER(DH, load_tester_diffie_hellman_create), - PLUGIN_PROVIDE(DH, MODP_NULL), + PLUGIN_REGISTER(KE, load_tester_diffie_hellman_create), + PLUGIN_PROVIDE(KE, MODP_NULL), PLUGIN_DEPENDS(CUSTOM, "load-tester"), PLUGIN_CALLBACK((plugin_feature_callback_t)register_load_tester, NULL), PLUGIN_PROVIDE(CUSTOM, "load-tester"), diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index ae21b3ef1..4c9f75cf7 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -266,10 +266,10 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) fprintf(out, "_%u", ks); } } - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL)) { - fprintf(out, "/%N", diffie_hellman_group_names, alg); + fprintf(out, "/%N", key_exchange_method_names, alg); } if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL) && alg == EXT_SEQ_NUMBERS) @@ -855,7 +855,7 @@ static void list_algs(FILE *out) ext_out_function_t xof; key_derivation_function_t kdf; drbg_type_t drbg; - diffie_hellman_group_t group; + key_exchange_method_t group; rng_quality_t quality; const char *plugin_name; int len; @@ -928,10 +928,10 @@ static void list_algs(FILE *out) enumerator->destroy(enumerator); fprintf(out, "\n dh-group: "); len = 13; - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + enumerator = lib->crypto->create_ke_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) { - print_alg(out, &len, diffie_hellman_group_names, group, plugin_name); + print_alg(out, &len, key_exchange_method_names, group, plugin_name); } enumerator->destroy(enumerator); fprintf(out, "\n random-gen:"); diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index 1f5ba676e..bacb7b101 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -230,10 +230,10 @@ static void list_child_ipsec(vici_builder_t *b, child_sa_t *child) b->add_kv(b, "integ-keysize", "%u", ks); } } - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL)) { - b->add_kv(b, "dh-group", "%N", diffie_hellman_group_names, alg); + b->add_kv(b, "dh-group", "%N", key_exchange_method_names, alg); } if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL) && alg == EXT_SEQ_NUMBERS) @@ -489,9 +489,9 @@ static void list_ike(private_vici_query_t *this, vici_builder_t *b, { b->add_kv(b, "prf-alg", "%N", pseudo_random_function_names, alg); } - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL)) + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL)) { - b->add_kv(b, "dh-group", "%N", diffie_hellman_group_names, alg); + b->add_kv(b, "dh-group", "%N", key_exchange_method_names, alg); } } add_condition(b, ike_sa, "ppk", COND_PPK); @@ -1304,7 +1304,7 @@ CALLBACK(get_algorithms, vici_message_t*, ext_out_function_t xof; key_derivation_function_t kdf; drbg_type_t drbg; - diffie_hellman_group_t group; + key_exchange_method_t group; rng_quality_t quality; const char *plugin_name; @@ -1383,10 +1383,10 @@ CALLBACK(get_algorithms, vici_message_t*, b->end_section(b); b->begin_section(b, "dh"); - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + enumerator = lib->crypto->create_ke_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) { - add_algorithm(b, diffie_hellman_group_names, group, plugin_name); + add_algorithm(b, key_exchange_method_names, group, plugin_name); } enumerator->destroy(enumerator); b->end_section(b); diff --git a/src/libcharon/sa/authenticator.c b/src/libcharon/sa/authenticator.c index 17c82dee5..8dba75d8a 100644 --- a/src/libcharon/sa/authenticator.c +++ b/src/libcharon/sa/authenticator.c @@ -121,7 +121,7 @@ authenticator_t *authenticator_create_verifier( * Described in header. */ authenticator_t *authenticator_create_v1(ike_sa_t *ike_sa, bool initiator, - auth_method_t auth_method, diffie_hellman_t *dh, + auth_method_t auth_method, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload) { diff --git a/src/libcharon/sa/authenticator.h b/src/libcharon/sa/authenticator.h index 90b79bfed..cafea503c 100644 --- a/src/libcharon/sa/authenticator.h +++ b/src/libcharon/sa/authenticator.h @@ -238,7 +238,7 @@ authenticator_t *authenticator_create_verifier( * @return authenticator, NULL if not supported */ authenticator_t *authenticator_create_v1(ike_sa_t *ike_sa, bool initiator, - auth_method_t auth_method, diffie_hellman_t *dh, + auth_method_t auth_method, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload); diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 401bf0729..2c77ee2c6 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -110,6 +110,11 @@ struct private_child_sa_t { */ chunk_t integ_r; + /** + * Whether the registered outbound SA was created as initiator + */ + bool initiator; + /** * Whether the outbound SA has only been registered yet during a rekeying */ @@ -1420,13 +1425,13 @@ static bool install_outbound_immediately(private_child_sa_t *this) METHOD(child_sa_t, register_outbound, status_t, private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi, - uint16_t cpi, bool tfcv3) + uint16_t cpi, bool initiator, bool tfcv3) { status_t status; if (install_outbound_immediately(this)) { - status = install_internal(this, encr, integ, spi, cpi, FALSE, FALSE, + status = install_internal(this, encr, integ, spi, cpi, initiator, FALSE, tfcv3); } else @@ -1440,6 +1445,7 @@ METHOD(child_sa_t, register_outbound, status_t, this->other_cpi = cpi; this->encr_r = chunk_clone(encr); this->integ_r = chunk_clone(integ); + this->initiator = initiator; this->tfcv3 = tfcv3; status = SUCCESS; } @@ -1457,8 +1463,8 @@ METHOD(child_sa_t, install_outbound, status_t, if (!(this->outbound_state & CHILD_OUTBOUND_SA)) { status = install_internal(this, this->encr_r, this->integ_r, - this->other_spi, this->other_cpi, FALSE, - FALSE, this->tfcv3); + this->other_spi, this->other_cpi, + this->initiator, FALSE, this->tfcv3); chunk_clear(&this->encr_r); chunk_clear(&this->integ_r); } diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index 73488c127..37f00277e 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -442,11 +442,13 @@ struct child_sa_t { * @param integ integrity key (cloned) * @param spi SPI to use, allocated for inbound * @param cpi CPI to use, allocated for outbound + * @param initiator TRUE if initiator of exchange resulting in this SA * @param tfcv3 TRUE if peer supports ESPv3 TFC * @return SUCCESS or FAILED */ status_t (*register_outbound)(child_sa_t *this, chunk_t encr, chunk_t integ, - uint32_t spi, uint16_t cpi, bool tfcv3); + uint32_t spi, uint16_t cpi, bool initiator, + bool tfcv3); /** * Install the outbound policies and, if not already done, the outbound SA diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index e7ada463b..0d554204d 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1883,6 +1883,7 @@ METHOD(ike_sa_t, delete_, status_t, { case IKE_ESTABLISHED: case IKE_REKEYING: + case IKE_REKEYED: if (time_monotonic(NULL) >= this->stats[STAT_DELETE] && !(this->version == IKEV1 && this->state == IKE_REKEYING)) { /* IKE_SA hard lifetime hit, ignored for reauthenticated diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 743e0ddde..e860784de 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1879,8 +1879,12 @@ METHOD(ike_sa_manager_t, checkin, void, other_id = ike_sa->get_other_eap_id(ike_sa); other = ike_sa->get_other_host(ike_sa); - DBG2(DBG_MGR, "checkin IKE_SA %s[%u]", ike_sa->get_name(ike_sa), - ike_sa->get_unique_id(ike_sa)); + DBG2(DBG_MGR, "checkin %N SA %s[%u] with SPIs %.16"PRIx64"_i " + "%.16"PRIx64"_r", ike_version_names, + ike_sa_id->get_ike_version(ike_sa_id), ike_sa->get_name(ike_sa), + ike_sa->get_unique_id(ike_sa), + be64toh(ike_sa_id->get_initiator_spi(ike_sa_id)), + be64toh(ike_sa_id->get_responder_spi(ike_sa_id))); /* look for the entry */ if (get_entry_by_sa(this, ike_sa_id, ike_sa, &entry, &segment) == SUCCESS) diff --git a/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.c b/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.c index 529d0f9bb..368429799 100644 --- a/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.c @@ -78,7 +78,7 @@ METHOD(authenticator_t, destroy, void, * Described in header. */ hybrid_authenticator_t *hybrid_authenticator_create(ike_sa_t *ike_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload) { diff --git a/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.h b/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.h index 0a0be1aad..6d725d08e 100644 --- a/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.h +++ b/src/libcharon/sa/ikev1/authenticators/hybrid_authenticator.h @@ -50,7 +50,7 @@ struct hybrid_authenticator_t { * @return hybrid authenticator */ hybrid_authenticator_t *hybrid_authenticator_create(ike_sa_t *ike_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload); diff --git a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c index 36c9af289..e99f1276a 100644 --- a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c @@ -45,7 +45,7 @@ struct private_psk_v1_authenticator_t { /** * DH key exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Others DH public value @@ -75,7 +75,7 @@ METHOD(authenticator_t, build, status_t, keymat_v1_t *keymat; chunk_t hash, dh; - if (!this->dh->get_my_public_value(this->dh, &dh)) + if (!this->dh->get_public_key(this->dh, &dh)) { return FAILED; } @@ -112,7 +112,7 @@ METHOD(authenticator_t, process, status_t, return FAILED; } - if (!this->dh->get_my_public_value(this->dh, &dh)) + if (!this->dh->get_public_key(this->dh, &dh)) { return FAILED; } @@ -151,7 +151,7 @@ METHOD(authenticator_t, destroy, void, * Described in header. */ psk_v1_authenticator_t *psk_v1_authenticator_create(ike_sa_t *ike_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload, bool hybrid) { diff --git a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.h b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.h index 68374046b..be370670a 100644 --- a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.h +++ b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.h @@ -51,7 +51,7 @@ struct psk_v1_authenticator_t { * @return PSK authenticator */ psk_v1_authenticator_t *psk_v1_authenticator_create(ike_sa_t *ike_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload, bool hybrid); diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c index dc1399282..867952602 100644 --- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c @@ -46,7 +46,7 @@ struct private_pubkey_v1_authenticator_t { /** * DH key exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Others DH public value @@ -96,7 +96,7 @@ METHOD(authenticator_t, build, status_t, return NOT_FOUND; } - if (!this->dh->get_my_public_value(this->dh, &dh)) + if (!this->dh->get_public_key(this->dh, &dh)) { private->destroy(private); return FAILED; @@ -181,7 +181,7 @@ METHOD(authenticator_t, process, status_t, } id = this->ike_sa->get_other_id(this->ike_sa); - if (!this->dh->get_my_public_value(this->dh, &dh)) + if (!this->dh->get_public_key(this->dh, &dh)) { return FAILED; } @@ -238,7 +238,7 @@ METHOD(authenticator_t, destroy, void, * Described in header. */ pubkey_v1_authenticator_t *pubkey_v1_authenticator_create(ike_sa_t *ike_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload, key_type_t type) { diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.h b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.h index 20c98b37a..8ae10b732 100644 --- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.h +++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.h @@ -51,7 +51,7 @@ struct pubkey_v1_authenticator_t { * @return pubkey authenticator */ pubkey_v1_authenticator_t *pubkey_v1_authenticator_create(ike_sa_t *ike_sa, - bool initiator, diffie_hellman_t *dh, + bool initiator, key_exchange_t *dh, chunk_t dh_value, chunk_t sa_payload, chunk_t id_payload, key_type_t type); diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c index 8b79d246b..64de3d95d 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.c +++ b/src/libcharon/sa/ikev1/keymat_v1.c @@ -314,7 +314,7 @@ static void adjust_keylen(uint16_t alg, chunk_t *key) } METHOD(keymat_v1_t, derive_ike_keys, bool, - private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh, + private_keymat_v1_t *this, proposal_t *proposal, key_exchange_t *dh, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, auth_method_t auth, shared_key_t *shared_key) { @@ -494,7 +494,7 @@ METHOD(keymat_v1_t, derive_ike_keys, bool, return FALSE; } - if (!dh->get_my_public_value(dh, &dh_me)) + if (!dh->get_public_key(dh, &dh_me)) { return FALSE; } @@ -539,7 +539,7 @@ static bool derive_child_keymat(private_keymat_v1_t *this, chunk_t seed, } METHOD(keymat_v1_t, derive_child_keys, bool, - private_keymat_v1_t *this, proposal_t *proposal, diffie_hellman_t *dh, + private_keymat_v1_t *this, proposal_t *proposal, key_exchange_t *dh, uint32_t spi_i, uint32_t spi_r, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r) { @@ -914,10 +914,10 @@ METHOD(keymat_t, get_version, ike_version_t, return IKEV1; } -METHOD(keymat_t, create_dh, diffie_hellman_t*, - private_keymat_v1_t *this, diffie_hellman_group_t group) +METHOD(keymat_t, create_ke, key_exchange_t*, + private_keymat_v1_t *this, key_exchange_method_t method) { - return lib->crypto->create_dh(lib->crypto, group); + return lib->crypto->create_ke(lib->crypto, method); } METHOD(keymat_t, create_nonce_gen, nonce_gen_t*, @@ -956,7 +956,7 @@ keymat_v1_t *keymat_v1_create(bool initiator) .public = { .keymat = { .get_version = _get_version, - .create_dh = _create_dh, + .create_ke = _create_ke, .create_nonce_gen = _create_nonce_gen, .get_aead = _get_aead, .destroy = _destroy, diff --git a/src/libcharon/sa/ikev1/keymat_v1.h b/src/libcharon/sa/ikev1/keymat_v1.h index df697bd24..413385d3d 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.h +++ b/src/libcharon/sa/ikev1/keymat_v1.h @@ -44,7 +44,7 @@ struct keymat_v1_t { * crypters and authentication functions. * * @param proposal selected algorithms - * @param dh diffie hellman key allocated by create_dh() + * @param dh diffie hellman key allocated by create_ke() * @param dh_other public DH value from other peer * @param nonce_i initiators nonce value * @param nonce_r responders nonce value @@ -54,7 +54,7 @@ struct keymat_v1_t { * @return TRUE on success */ bool (*derive_ike_keys)(keymat_v1_t *this, proposal_t *proposal, - diffie_hellman_t *dh, chunk_t dh_other, + key_exchange_t *dh, chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, auth_method_t auth, shared_key_t *shared_key); @@ -73,7 +73,7 @@ struct keymat_v1_t { * @param integ_r allocated responders integrity key */ bool (*derive_child_keys)(keymat_v1_t *this, proposal_t *proposal, - diffie_hellman_t *dh, uint32_t spi_i, uint32_t spi_r, + key_exchange_t *dh, uint32_t spi_i, uint32_t spi_r, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r); diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index 600f15faa..2520b6a93 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -63,7 +63,7 @@ struct private_phase1_t { /** * DH exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Keymat derivation (from SA) @@ -210,9 +210,9 @@ METHOD(phase1_t, create_hasher, bool, } METHOD(phase1_t, create_dh, bool, - private_phase1_t *this, diffie_hellman_group_t group) + private_phase1_t *this, key_exchange_method_t group) { - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, group); + this->dh = this->keymat->keymat.create_ke(&this->keymat->keymat, group); return this->dh != NULL; } @@ -705,8 +705,8 @@ METHOD(phase1_t, add_nonce_ke, bool, nonce_gen_t *nonceg; chunk_t nonce; - ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, - this->dh); + ke_payload = ke_payload_create_from_key_exchange(PLV1_KEY_EXCHANGE, + this->dh); if (!ke_payload) { DBG1(DBG_IKE, "creating KE payload failed"); @@ -756,7 +756,7 @@ METHOD(phase1_t, get_nonce_ke, bool, return FALSE; } this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload)); - if (!this->dh->set_other_public_value(this->dh, this->dh_value)) + if (!this->dh->set_public_key(this->dh, this->dh_value)) { DBG1(DBG_IKE, "unable to apply received KE value"); return FALSE; diff --git a/src/libcharon/sa/ikev1/phase1.h b/src/libcharon/sa/ikev1/phase1.h index 6bc318a8f..d3a91b6e5 100644 --- a/src/libcharon/sa/ikev1/phase1.h +++ b/src/libcharon/sa/ikev1/phase1.h @@ -25,7 +25,7 @@ typedef struct phase1_t phase1_t; #include -#include +#include /** * Common phase 1 helper for main and aggressive mode. @@ -45,7 +45,7 @@ struct phase1_t { * @param group negotiated DH group * @return TRUE if group supported */ - bool (*create_dh)(phase1_t *this, diffie_hellman_group_t group); + bool (*create_dh)(phase1_t *this, key_exchange_method_t group); /** * Derive key material. diff --git a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c index 7da0825c5..0184cb55e 100644 --- a/src/libcharon/sa/ikev1/tasks/aggressive_mode.c +++ b/src/libcharon/sa/ikev1/tasks/aggressive_mode.c @@ -252,8 +252,9 @@ METHOD(task_t, build_i, status_t, message->add_payload(message, &sa_payload->payload_interface); - group = this->ike_cfg->get_dh_group(this->ike_cfg); - if (group == MODP_NONE) + group = this->ike_cfg->get_algorithm(this->ike_cfg, + KEY_EXCHANGE_METHOD); + if (!group) { DBG1(DBG_IKE, "DH group selection failed"); return FAILED; @@ -261,7 +262,7 @@ METHOD(task_t, build_i, status_t, if (!this->ph1->create_dh(this->ph1, group)) { DBG1(DBG_IKE, "DH group %N not supported", - diffie_hellman_group_names, group); + key_exchange_method_names, group); return FAILED; } if (!this->ph1->add_nonce_ke(this->ph1, message)) @@ -438,7 +439,7 @@ METHOD(task_t, process_r, status_t, } if (!this->proposal->get_algorithm(this->proposal, - DIFFIE_HELLMAN_GROUP, &group, NULL)) + KEY_EXCHANGE_METHOD, &group, NULL)) { DBG1(DBG_IKE, "DH group selection failed"); return send_notify(this, INVALID_KEY_INFORMATION); diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c index 618986ad0..9ab34ce92 100644 --- a/src/libcharon/sa/ikev1/tasks/main_mode.c +++ b/src/libcharon/sa/ikev1/tasks/main_mode.c @@ -314,7 +314,7 @@ METHOD(task_t, build_i, status_t, return send_notify(this, NO_PROPOSAL_CHOSEN); } if (!this->proposal->get_algorithm(this->proposal, - DIFFIE_HELLMAN_GROUP, &group, NULL)) + KEY_EXCHANGE_METHOD, &group, NULL)) { DBG1(DBG_IKE, "DH group selection failed"); return send_notify(this, NO_PROPOSAL_CHOSEN); @@ -428,7 +428,7 @@ METHOD(task_t, process_r, status_t, return send_notify(this, INVALID_KEY_INFORMATION); } if (!this->proposal->get_algorithm(this->proposal, - DIFFIE_HELLMAN_GROUP, &group, NULL)) + KEY_EXCHANGE_METHOD, &group, NULL)) { DBG1(DBG_IKE, "DH group selection failed"); return send_notify(this, INVALID_KEY_INFORMATION); diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index c101ff357..3d2e3efbe 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -137,7 +137,7 @@ struct private_quick_mode_t { /** * DH exchange, when PFS is in use */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Negotiated lifetime of new SA @@ -486,8 +486,8 @@ static bool add_ke(private_quick_mode_t *this, message_t *message) { ke_payload_t *ke_payload; - ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, - this->dh); + ke_payload = ke_payload_create_from_key_exchange(PLV1_KEY_EXCHANGE, + this->dh); if (!ke_payload) { DBG1(DBG_IKE, "creating KE payload failed"); @@ -510,7 +510,7 @@ static bool get_ke(private_quick_mode_t *this, message_t *message) DBG1(DBG_IKE, "KE payload missing"); return FALSE; } - if (!this->dh->set_other_public_value(this->dh, + if (!this->dh->set_public_key(this->dh, ke_payload->get_key_exchange_data(ke_payload))) { DBG1(DBG_IKE, "unable to apply received KE value"); @@ -782,10 +782,10 @@ static status_t send_notify(private_quick_mode_t *this, notify_type_t type) /** * Prepare a list of proposals from child_config containing only the specified - * DH group, unless it is set to MODP_NONE. + * DH group, unless it is set to KE_NONE. */ static linked_list_t *get_proposals(private_quick_mode_t *this, - diffie_hellman_group_t group) + key_exchange_method_t group) { linked_list_t *list; proposal_t *proposal; @@ -795,15 +795,15 @@ static linked_list_t *get_proposals(private_quick_mode_t *this, enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &proposal)) { - if (group != MODP_NONE) + if (group != KE_NONE) { - if (!proposal->has_dh_group(proposal, group)) + if (!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, group)) { list->remove_at(list, enumerator); proposal->destroy(proposal); continue; } - proposal->promote_dh_group(proposal, group); + proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, group); } proposal->set_spi(proposal, this->spi_i); } @@ -822,7 +822,7 @@ METHOD(task_t, build_i, status_t, sa_payload_t *sa_payload; linked_list_t *list, *tsi, *tsr; proposal_t *proposal; - diffie_hellman_group_t group; + key_exchange_method_t group; encap_t encap; this->mode = this->config->get_mode(this->config); @@ -866,14 +866,15 @@ METHOD(task_t, build_i, status_t, return FAILED; } - group = this->config->get_dh_group(this->config); - if (group != MODP_NONE) + group = this->config->get_algorithm(this->config, + KEY_EXCHANGE_METHOD); + if (group != KE_NONE) { proposal_t *proposal; uint16_t preferred_group; proposal = this->ike_sa->get_proposal(this->ike_sa); - proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &preferred_group, NULL); /* try the negotiated DH group from IKE_SA */ list = get_proposals(this, preferred_group); @@ -888,19 +889,19 @@ METHOD(task_t, build_i, status_t, list = get_proposals(this, group); } - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, + this->dh = this->keymat->keymat.create_ke(&this->keymat->keymat, group); if (!this->dh) { DBG1(DBG_IKE, "configured DH group %N not supported", - diffie_hellman_group_names, group); + key_exchange_method_names, group); list->destroy_offset(list, offsetof(proposal_t, destroy)); return FAILED; } } else { - list = get_proposals(this, MODP_NONE); + list = get_proposals(this, KE_NONE); } get_lifetimes(this); @@ -915,7 +916,7 @@ METHOD(task_t, build_i, status_t, { return FAILED; } - if (group != MODP_NONE) + if (group != KE_NONE) { if (!add_ke(this, message)) { @@ -1165,14 +1166,14 @@ METHOD(task_t, process_r, status_t, } if (this->proposal->get_algorithm(this->proposal, - DIFFIE_HELLMAN_GROUP, &group, NULL)) + KEY_EXCHANGE_METHOD, &group, NULL)) { - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, + this->dh = this->keymat->keymat.create_ke(&this->keymat->keymat, group); if (!this->dh) { DBG1(DBG_IKE, "negotiated DH group %N not supported", - diffie_hellman_group_names, group); + key_exchange_method_names, group); return send_notify(this, INVALID_KEY_INFORMATION); } if (!get_ke(this, message)) diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c index ae3a11535..c8a9c7117 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.c +++ b/src/libcharon/sa/ikev2/keymat_v2.c @@ -84,10 +84,10 @@ METHOD(keymat_t, get_version, ike_version_t, return IKEV2; } -METHOD(keymat_t, create_dh, diffie_hellman_t*, - private_keymat_v2_t *this, diffie_hellman_group_t group) +METHOD(keymat_t, create_ke, key_exchange_t*, + private_keymat_v2_t *this, key_exchange_method_t method) { - return lib->crypto->create_dh(lib->crypto, group); + return lib->crypto->create_ke(lib->crypto, method); } METHOD(keymat_t, create_nonce_gen, nonce_gen_t*, @@ -237,7 +237,7 @@ static bool set_aead_keys(private_keymat_v2_t *this, uint16_t enc_alg, } METHOD(keymat_v2_t, derive_ike_keys, bool, - private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh, + private_keymat_v2_t *this, proposal_t *proposal, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, pseudo_random_function_t rekey_function, chunk_t rekey_skd) { @@ -523,7 +523,7 @@ METHOD(keymat_v2_t, derive_ike_keys_ppk, bool, } METHOD(keymat_v2_t, derive_child_keys, bool, - private_keymat_v2_t *this, proposal_t *proposal, diffie_hellman_t *dh, + private_keymat_v2_t *this, proposal_t *proposal, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r) { @@ -796,7 +796,7 @@ keymat_v2_t *keymat_v2_create(bool initiator) .public = { .keymat = { .get_version = _get_version, - .create_dh = _create_dh, + .create_ke = _create_ke, .create_nonce_gen = _create_nonce_gen, .get_aead = _get_aead, .destroy = _destroy, diff --git a/src/libcharon/sa/ikev2/keymat_v2.h b/src/libcharon/sa/ikev2/keymat_v2.h index 10ced84e5..60bac653b 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.h +++ b/src/libcharon/sa/ikev2/keymat_v2.h @@ -44,7 +44,7 @@ struct keymat_v2_t { * crypters and authentication functions. * * @param proposal selected algorithms - * @param dh diffie hellman key allocated by create_dh() + * @param dh diffie hellman key allocated by create_ke() * @param nonce_i initiators nonce value * @param nonce_r responders nonce value * @param id IKE_SA identifier @@ -53,7 +53,7 @@ struct keymat_v2_t { * @return TRUE on success */ bool (*derive_ike_keys)(keymat_v2_t *this, proposal_t *proposal, - diffie_hellman_t *dh, chunk_t nonce_i, + key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, pseudo_random_function_t rekey_function, chunk_t rekey_skd); @@ -77,7 +77,7 @@ struct keymat_v2_t { * If no PFS is used for the CHILD_SA, dh can be NULL. * * @param proposal selected algorithms - * @param dh diffie hellman key allocated by create_dh(), or NULL + * @param dh diffie hellman key allocated by create_ke(), or NULL * @param nonce_i initiators nonce value * @param nonce_r responders nonce value * @param encr_i chunk to write initiators encryption key to @@ -87,7 +87,7 @@ struct keymat_v2_t { * @return TRUE on success */ bool (*derive_child_keys)(keymat_v2_t *this, - proposal_t *proposal, diffie_hellman_t *dh, + proposal_t *proposal, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r); diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index c9ea9792b..f1228ab07 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2018 Tobias Brunner + * Copyright (C) 2007-2019 Tobias Brunner * Copyright (C) 2007-2010 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -79,14 +80,24 @@ struct private_task_manager_t { uint32_t mid; /** - * packet(s) for retransmission + * Helper to defragment the request + */ + message_t *defrag; + + /** + * Hash of the current message, or its first fragment + */ + uint8_t hash[HASH_SIZE_SHA1]; + + /** + * Packet(s) for retransmissions (mid-1) */ array_t *packets; /** - * Helper to defragment the request + * Hash of the previously received message, or its first fragment */ - message_t *defrag; + uint8_t prev_hash[HASH_SIZE_SHA1]; } responding; @@ -464,6 +475,40 @@ METHOD(task_manager_t, retransmit, status_t, return INVALID_STATE; } +/** + * Derive IKE keys if necessary + */ +static bool derive_keys(private_task_manager_t *this, array_t *tasks) +{ + enumerator_t *enumerator; + task_t *task; + + enumerator = array_create_enumerator(tasks); + while (enumerator->enumerate(enumerator, (void*)&task)) + { + if (task->get_type(task) == TASK_IKE_INIT) + { + ike_init_t *ike_init = (ike_init_t*)task; + + switch (ike_init->derive_keys(ike_init)) + { + case SUCCESS: + array_remove_at(tasks, enumerator); + task->destroy(task); + break; + case NEED_MORE: + break; + default: + enumerator->destroy(enumerator); + return FALSE; + } + break; + } + } + enumerator->destroy(enumerator); + return TRUE; +} + METHOD(task_manager_t, initiate, status_t, private_task_manager_t *this) { @@ -472,6 +517,7 @@ METHOD(task_manager_t, initiate, status_t, message_t *message; host_t *me, *other; exchange_type_t exchange = 0; + bool result; if (this->initiating.type != EXCHANGE_TYPE_UNDEFINED) { @@ -597,6 +643,11 @@ METHOD(task_manager_t, initiate, status_t, } else { + if (!derive_keys(this, this->active_tasks)) + { + return DESTROY_ME; + } + DBG2(DBG_IKE, "reinitiating already active tasks"); enumerator = array_create_enumerator(this->active_tasks); while (enumerator->enumerate(enumerator, &task)) @@ -686,17 +737,47 @@ METHOD(task_manager_t, initiate, status_t, return initiate(this); } - if (!generate_message(this, message, &this->initiating.packets)) + result = generate_message(this, message, &this->initiating.packets); + + if (result) { - /* message generation failed. There is nothing more to do than to - * close the SA */ - message->destroy(message); - flush(this); - charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); - return DESTROY_ME; + enumerator = array_create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, &task)) + { + if (!task->post_build) + { + continue; + } + switch (task->post_build(task, message)) + { + case SUCCESS: + array_remove_at(this->active_tasks, enumerator); + task->destroy(task); + break; + case NEED_MORE: + break; + default: + /* critical failure, destroy IKE_SA */ + result = FALSE; + break; + } + } + enumerator->destroy(enumerator); } message->destroy(message); + if (!result) + { /* message generation failed. There is nothing more to do than to + * close the SA */ + flush(this); + if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING && + this->ike_sa->get_state(this->ike_sa) != IKE_REKEYED) + { + charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE); + } + return DESTROY_ME; + } + array_compress(this->active_tasks); array_compress(this->queued_tasks); @@ -806,6 +887,31 @@ static status_t process_response(private_task_manager_t *this, } enumerator->destroy(enumerator); + enumerator = array_create_enumerator(this->active_tasks); + while (enumerator->enumerate(enumerator, &task)) + { + if (!task->post_process) + { + continue; + } + switch (task->post_process(task, message)) + { + case SUCCESS: + array_remove_at(this->active_tasks, enumerator); + task->destroy(task); + break; + case NEED_MORE: + break; + default: + /* critical failure, destroy IKE_SA */ + array_remove_at(this->active_tasks, enumerator); + enumerator->destroy(enumerator); + task->destroy(task); + return DESTROY_ME; + } + } + enumerator->destroy(enumerator); + this->initiating.mid++; this->initiating.type = EXCHANGE_TYPE_UNDEFINED; clear_packets(this->initiating.packets); @@ -816,13 +922,15 @@ static status_t process_response(private_task_manager_t *this, } /** - * handle exchange collisions + * Handle exchange collisions, returns TRUE if the given passive task was + * adopted by the active task and the task manager lost control over it. */ static bool handle_collisions(private_task_manager_t *this, task_t *task) { enumerator_t *enumerator; task_t *active; task_type_t type; + bool adopted = FALSE; type = task->get_type(task); @@ -840,7 +948,7 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task) if (type == TASK_IKE_REKEY || type == TASK_IKE_DELETE) { ike_rekey_t *rekey = (ike_rekey_t*)active; - rekey->collide(rekey, task); + adopted = rekey->collide(rekey, task); break; } continue; @@ -848,7 +956,7 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task) if (type == TASK_CHILD_REKEY || type == TASK_CHILD_DELETE) { child_rekey_t *rekey = (child_rekey_t*)active; - rekey->collide(rekey, task); + adopted = rekey->collide(rekey, task); break; } continue; @@ -856,11 +964,11 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task) continue; } enumerator->destroy(enumerator); - return TRUE; + return adopted; } enumerator->destroy(enumerator); } - return FALSE; + return adopted; } /** @@ -947,7 +1055,34 @@ static status_t build_response(private_task_manager_t *this, message_t *request) /* message complete, send it */ clear_packets(this->responding.packets); result = generate_message(this, message, &this->responding.packets); + + if (result && !delete) + { + enumerator = array_create_enumerator(this->passive_tasks); + while (enumerator->enumerate(enumerator, &task)) + { + if (!task->post_build) + { + continue; + } + switch (task->post_build(task, message)) + { + case SUCCESS: + array_remove_at(this->passive_tasks, enumerator); + task->destroy(task); + break; + case NEED_MORE: + break; + default: + /* critical failure, destroy IKE_SA */ + result = FALSE; + break; + } + } + enumerator->destroy(enumerator); + } message->destroy(message); + if (id) { id->set_responder_spi(id, responder_spi); @@ -1256,6 +1391,31 @@ static status_t process_request(private_task_manager_t *this, } enumerator->destroy(enumerator); + enumerator = array_create_enumerator(this->passive_tasks); + while (enumerator->enumerate(enumerator, &task)) + { + if (!task->post_process) + { + continue; + } + switch (task->post_process(task, message)) + { + case SUCCESS: + array_remove_at(this->passive_tasks, enumerator); + task->destroy(task); + break; + case NEED_MORE: + break; + default: + /* critical failure, destroy IKE_SA */ + array_remove_at(this->passive_tasks, enumerator); + enumerator->destroy(enumerator); + task->destroy(task); + return DESTROY_ME; + } + } + enumerator->destroy(enumerator); + return build_response(this, message); } @@ -1278,27 +1438,46 @@ METHOD(task_manager_t, get_mid, uint32_t, return initiate ? this->initiating.mid : this->responding.mid; } +/** + * Hash the given message with SHA-1 + */ +static bool hash_message(message_t *msg, uint8_t hash[HASH_SIZE_SHA1]) +{ + hasher_t *hasher; + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || + !hasher->get_hash(hasher, msg->get_packet_data(msg), hash)) + { + DESTROY_IF(hasher); + return FALSE; + } + hasher->destroy(hasher); + return TRUE; +} + /** * Handle the given IKE fragment, if it is one. * * Returns SUCCESS if the message is not a fragment, and NEED_MORE if it was * handled properly. Error states are returned if the fragment was invalid or - * the reassembled message could not have been processed properly. + * the reassembled message could not be processed properly. */ static status_t handle_fragment(private_task_manager_t *this, message_t **defrag, message_t *msg) { - message_t *reassembled; + encrypted_fragment_payload_t *fragment; status_t status; - if (*defrag && (*defrag)->get_message_id(*defrag) < msg->get_message_id(msg)) - { - /* clear fragments of an incompletely received retransmitted message */ - (*defrag)->destroy(*defrag); - *defrag = NULL; - } - if (!msg->get_payload(msg, PLV2_FRAGMENT)) + fragment = (encrypted_fragment_payload_t*)msg->get_payload(msg, + PLV2_FRAGMENT); + if (!fragment) { + /* ignore reassembled messages, we collected their fragments below */ + if (msg != *defrag) + { + hash_message(msg, this->responding.hash); + } return SUCCESS; } if (!*defrag) @@ -1310,18 +1489,26 @@ static status_t handle_fragment(private_task_manager_t *this, } } status = (*defrag)->add_fragment(*defrag, msg); + + if (status == NEED_MORE || status == SUCCESS) + { + /* to detect retransmissions we only hash the first fragment */ + if (fragment->get_fragment_number(fragment) == 1) + { + hash_message(msg, this->responding.hash); + } + } if (status == SUCCESS) { /* reinject the reassembled message */ - reassembled = *defrag; - *defrag = NULL; - status = this->ike_sa->process_message(this->ike_sa, reassembled); + status = this->ike_sa->process_message(this->ike_sa, *defrag); if (status == SUCCESS) { /* avoid processing the last fragment */ status = NEED_MORE; } - reassembled->destroy(reassembled); + (*defrag)->destroy(*defrag); + *defrag = NULL; } return status; } @@ -1383,6 +1570,36 @@ static status_t send_invalid_syntax(private_task_manager_t *this, return DESTROY_ME; } +/** + * Check for unsupported critical payloads + */ +static status_t has_unsupported_critical_payload(message_t *msg, uint8_t *type) +{ + enumerator_t *enumerator; + unknown_payload_t *unknown; + payload_t *payload; + status_t status = SUCCESS; + + enumerator = msg->create_payload_enumerator(msg); + while (enumerator->enumerate(enumerator, &payload)) + { + if (payload->get_type(payload) == PL_UNKNOWN) + { + unknown = (unknown_payload_t*)payload; + if (unknown->is_critical(unknown)) + { + *type = unknown->get_type(unknown); + DBG1(DBG_ENC, "payload type %N is not supported, " + "but payload is critical!", payload_type_names, *type); + status = NOT_SUPPORTED; + break; + } + } + } + enumerator->destroy(enumerator); + return status; +} + /** * Parse the given message and verify that it is valid. */ @@ -1391,34 +1608,22 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg) status_t parse_status, status; uint8_t type = 0; - parse_status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa)); + if (derive_keys(this, this->passive_tasks)) + { + parse_status = msg->parse_body(msg, this->ike_sa->get_keymat(this->ike_sa)); - if (parse_status == SUCCESS) - { /* check for unsupported critical payloads */ - enumerator_t *enumerator; - unknown_payload_t *unknown; - payload_t *payload; - - enumerator = msg->create_payload_enumerator(msg); - while (enumerator->enumerate(enumerator, &payload)) + if (parse_status == SUCCESS) { - if (payload->get_type(payload) == PL_UNKNOWN) - { - unknown = (unknown_payload_t*)payload; - if (unknown->is_critical(unknown)) - { - type = unknown->get_type(unknown); - DBG1(DBG_ENC, "payload type %N is not supported, " - "but payload is critical!", payload_type_names, type); - parse_status = NOT_SUPPORTED; - break; - } - } + parse_status = has_unsupported_critical_payload(msg, &type); } - enumerator->destroy(enumerator); - } - status = parse_status; + status = parse_status; + } + else + { /* there is no point in trying again */ + parse_status = INVALID_STATE; + status = DESTROY_ME; + } if (parse_status != SUCCESS) { @@ -1488,47 +1693,6 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg) return status; } -/** - * Check if a message with message ID 0 looks like it is used to synchronize - * the message IDs. - */ -static bool looks_like_mid_sync(private_task_manager_t *this, message_t *msg, - bool strict) -{ - enumerator_t *enumerator; - notify_payload_t *notify; - payload_t *payload; - bool found = FALSE, other = FALSE; - - if (msg->get_exchange_type(msg) == INFORMATIONAL) - { - enumerator = msg->create_payload_enumerator(msg); - while (enumerator->enumerate(enumerator, &payload)) - { - if (payload->get_type(payload) == PLV2_NOTIFY) - { - notify = (notify_payload_t*)payload; - switch (notify->get_notify_type(notify)) - { - case IKEV2_MESSAGE_ID_SYNC: - case IPSEC_REPLAY_COUNTER_SYNC: - found = TRUE; - continue; - default: - break; - } - } - if (strict) - { - other = TRUE; - break; - } - } - enumerator->destroy(enumerator); - } - return found && !other; -} - /** * Check whether we should reject the given request message */ @@ -1582,22 +1746,90 @@ static inline bool reject_request(private_task_manager_t *this, } return reject; } + /** * Check if a message with message ID 0 looks like it is used to synchronize - * the message IDs and we are prepared to process it. + * the message IDs. * - * Note: This is not called if the responder never sent a message before (i.e. - * we expect MID 0). + * Call this after checking the message with is_potential_mid_sync() first. */ static bool is_mid_sync(private_task_manager_t *this, message_t *msg) { - if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED && - this->ike_sa->supports_extension(this->ike_sa, - EXT_IKE_MESSAGE_ID_SYNC)) + enumerator_t *enumerator; + notify_payload_t *notify; + payload_t *payload; + bool found = FALSE, other = FALSE; + + enumerator = msg->create_payload_enumerator(msg); + while (enumerator->enumerate(enumerator, &payload)) { - return looks_like_mid_sync(this, msg, TRUE); + if (payload->get_type(payload) == PLV2_NOTIFY) + { + notify = (notify_payload_t*)payload; + switch (notify->get_notify_type(notify)) + { + case IKEV2_MESSAGE_ID_SYNC: + case IPSEC_REPLAY_COUNTER_SYNC: + found = TRUE; + continue; + default: + break; + } + } + other = TRUE; + break; } - return FALSE; + enumerator->destroy(enumerator); + return found && !other; +} + +/** + * Check if a message with message ID 0 looks like it could potentially be used + * to synchronize the message IDs and if we are prepared to process it. + * + * This may be called before the message body is parsed. + */ +static bool is_potential_mid_sync(private_task_manager_t *this, message_t *msg) +{ + return msg->get_exchange_type(msg) == INFORMATIONAL && + this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED && + this->ike_sa->supports_extension(this->ike_sa, + EXT_IKE_MESSAGE_ID_SYNC); +} + +/** + * Check if the given message is a retransmitted request + */ +static status_t is_retransmit(private_task_manager_t *this, message_t *msg) +{ + uint8_t hash[HASH_SIZE_SHA1]; + uint32_t mid; + + mid = msg->get_message_id(msg); + + if (mid == this->responding.mid) + { + return NEED_MORE; + } + + if (mid == this->responding.mid - 1 && + array_count(this->responding.packets)) + { + if (!hash_message(msg, hash)) + { + DBG1(DBG_IKE, "failed to hash message, ignored"); + return FAILED; + } + if (memeq_const(hash, this->responding.prev_hash, sizeof(hash))) + { + return ALREADY_DONE; + } + } + /* this includes fragments with fragment number > 1 (we only hash the first + * fragment), for which RFC 7383, section 2.6.1 explicitly does not allow + * retransmitting responses. we don't parse/verify these messages to check, + * we just ignore them. also included are MID sync messages with MID 0 */ + return INVALID_ARG; } METHOD(task_manager_t, process_message, status_t, @@ -1605,27 +1837,85 @@ METHOD(task_manager_t, process_message, status_t, { host_t *me, *other; status_t status; - uint32_t mid; + uint32_t mid, *expected_mid = NULL; bool schedule_delete_job = FALSE; + me = msg->get_destination(msg); + other = msg->get_source(msg); + mid = msg->get_message_id(msg); + charon->bus->message(charon->bus, msg, TRUE, FALSE); - status = parse_message(this, msg); - if (status != SUCCESS) + + if (msg->get_request(msg)) + { + bool potential_mid_sync = FALSE; + + switch (is_retransmit(this, msg)) + { + case ALREADY_DONE: + DBG1(DBG_IKE, "received retransmit of request with ID %d, " + "retransmitting response", mid); + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); + charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg); + send_packets(this, this->responding.packets, + msg->get_destination(msg), msg->get_source(msg)); + return SUCCESS; + case INVALID_ARG: + if (mid == 0 && is_potential_mid_sync(this, msg)) + { + potential_mid_sync = TRUE; + } + else + { + expected_mid = &this->responding.mid; + break; + } + /* check if it's actually an MID sync message */ + case NEED_MORE: + status = parse_message(this, msg); + if (potential_mid_sync && status == SUCCESS && + !is_mid_sync(this, msg)) + { + expected_mid = &this->responding.mid; + } + break; + case FAILED: + default: + return FAILED; + } + } + else + { + if (mid == this->initiating.mid) + { + status = parse_message(this, msg); + } + else + { + expected_mid = &this->initiating.mid; + } + } + + if (expected_mid) + { + DBG1(DBG_IKE, "received message ID %d, expected %d, ignored", + mid, *expected_mid); + return SUCCESS; + } + else if (status != SUCCESS) { return status; } - me = msg->get_destination(msg); - other = msg->get_source(msg); - /* if this IKE_SA is virgin, we check for a config */ - if (this->ike_sa->get_ike_cfg(this->ike_sa) == NULL) + if (!this->ike_sa->get_ike_cfg(this->ike_sa)) { ike_cfg_t *ike_cfg; ike_cfg = charon->backends->get_ike_cfg(charon->backends, me, other, IKEV2); - if (ike_cfg == NULL) + if (!ike_cfg) { /* no config found for these hosts, destroy */ DBG1(DBG_IKE, "no IKE config found for %H...%H, sending %N", @@ -1640,123 +1930,88 @@ METHOD(task_manager_t, process_message, status_t, schedule_delete_job = TRUE; } - mid = msg->get_message_id(msg); if (msg->get_request(msg)) { - if (mid == this->responding.mid || (mid == 0 && is_mid_sync(this, msg))) + /* special handling for requests happens in is_retransmit() + * reject initial messages if not received in specific states, + * after rekeying we only expect a DELETE in an INFORMATIONAL */ + if (reject_request(this, msg)) { - if (reject_request(this, msg)) - { - return FAILED; - } - if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) - { /* only do implicit updates without MOBIKE, and only force - * updates for IKE_AUTH (ports might change due to NAT-T) */ - this->ike_sa->update_hosts(this->ike_sa, me, other, - mid == 1 ? UPDATE_HOSTS_FORCE_ADDRS : 0); - } - status = handle_fragment(this, &this->responding.defrag, msg); - if (status != SUCCESS) - { - if (status == NEED_MORE) - { - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); - } - return status; - } - charon->bus->message(charon->bus, msg, TRUE, TRUE); - if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) - { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ - return SUCCESS; - } - switch (process_request(this, msg)) - { - case SUCCESS: - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); - this->responding.mid++; - break; - case NEED_MORE: - break; - default: - flush(this); - return DESTROY_ME; - } + return FAILED; } - else if ((mid == this->responding.mid - 1) && - array_count(this->responding.packets) && - !(mid == 0 && looks_like_mid_sync(this, msg, FALSE))) - { - status = handle_fragment(this, &this->responding.defrag, msg); - if (status != SUCCESS) - { - if (status == NEED_MORE) - { - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); - } - return status; - } - DBG1(DBG_IKE, "received retransmit of request with ID %d, " - "retransmitting response", mid); - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); - charon->bus->alert(charon->bus, ALERT_RETRANSMIT_RECEIVE, msg); - send_packets(this, this->responding.packets, - msg->get_destination(msg), msg->get_source(msg)); + if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) + { /* only do implicit updates without MOBIKE, and only force + * updates for IKE_AUTH (ports might change due to NAT-T) */ + this->ike_sa->update_hosts(this->ike_sa, me, other, + mid == 1 ? UPDATE_HOSTS_FORCE_ADDRS : 0); } - else + status = handle_fragment(this, &this->responding.defrag, msg); + if (status != SUCCESS) { - DBG1(DBG_IKE, "received message ID %d, expected %d, ignored", - mid, this->responding.mid); + if (status == NEED_MORE) + { + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); + } + return status; + } + charon->bus->message(charon->bus, msg, TRUE, TRUE); + if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) + { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ + return SUCCESS; + } + switch (process_request(this, msg)) + { + case SUCCESS: + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); + this->responding.mid++; + memcpy(this->responding.prev_hash, this->responding.hash, + sizeof(this->responding.prev_hash)); + break; + case NEED_MORE: + break; + default: + flush(this); + return DESTROY_ME; } } else { - if (mid == this->initiating.mid) - { - if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED || - this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING || - msg->get_exchange_type(msg) != IKE_SA_INIT) - { /* only do updates based on verified messages (or initial ones) */ - if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) - { /* only do implicit updates without MOBIKE, we force an - * update of the local address on IKE_SA_INIT as we might - * not know it yet, but never for the remote address */ - this->ike_sa->update_hosts(this->ike_sa, me, other, - mid == 0 ? UPDATE_HOSTS_FORCE_LOCAL : 0); - } + if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED || + this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING || + msg->get_exchange_type(msg) != IKE_SA_INIT) + { /* only do updates based on verified messages (or initial ones) */ + if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) + { /* only do implicit updates without MOBIKE, we force an + * update of the local address on IKE_SA_INIT as we might + * not know it yet, but never for the remote address */ + this->ike_sa->update_hosts(this->ike_sa, me, other, + mid == 0 ? UPDATE_HOSTS_FORCE_LOCAL : 0); } - status = handle_fragment(this, &this->initiating.defrag, msg); - if (status != SUCCESS) - { - if (status == NEED_MORE) - { - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); - } - return status; - } - charon->bus->message(charon->bus, msg, TRUE, TRUE); - if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) - { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ - return SUCCESS; - } - if (process_response(this, msg) != SUCCESS) - { - flush(this); - return DESTROY_ME; - } - this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, - time_monotonic(NULL)); } - else + status = handle_fragment(this, &this->initiating.defrag, msg); + if (status != SUCCESS) { - DBG1(DBG_IKE, "received message ID %d, expected %d, ignored", - mid, this->initiating.mid); + if (status == NEED_MORE) + { + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); + } + return status; + } + charon->bus->message(charon->bus, msg, TRUE, TRUE); + if (msg->get_exchange_type(msg) == EXCHANGE_TYPE_UNDEFINED) + { /* ignore messages altered to EXCHANGE_TYPE_UNDEFINED */ return SUCCESS; } + if (process_response(this, msg) != SUCCESS) + { + flush(this); + return DESTROY_ME; + } + this->ike_sa->set_statistic(this->ike_sa, STAT_INBOUND, + time_monotonic(NULL)); } if (schedule_delete_job) diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 0136377a8..1c0d7cc77 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -117,7 +117,7 @@ struct private_child_create_t { /** * optional diffie hellman exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Applying DH public value failed? @@ -127,7 +127,7 @@ struct private_child_create_t { /** * group used for DH exchange */ - diffie_hellman_group_t dh_group; + key_exchange_method_t dh_group; /** * IKE_SAs keymat @@ -325,10 +325,11 @@ static bool update_and_check_proposals(private_child_create_t *this) proposal->set_spi(proposal, this->my_spi); /* move the selected DH group to the front, if any */ - if (this->dh_group != MODP_NONE) + if (this->dh_group != KE_NONE) { /* proposals that don't contain the selected group are * moved to the back */ - if (!proposal->promote_dh_group(proposal, this->dh_group)) + if (!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { this->proposals->remove_at(this->proposals, enumerator); other_dh_groups->insert_last(other_dh_groups, proposal); @@ -348,7 +349,7 @@ static bool update_and_check_proposals(private_child_create_t *this) enumerator->destroy(enumerator); other_dh_groups->destroy(other_dh_groups); - return this->dh_group == MODP_NONE || found; + return this->dh_group == KE_NONE || found; } /** @@ -518,7 +519,7 @@ static status_t select_and_install(private_child_create_t *this, if (no_dh) { - flags |= PROPOSAL_SKIP_DH; + flags |= PROPOSAL_SKIP_KE; } if (!this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) && !lib->settings->get_bool(lib->settings, "%s.accept_private_algs", @@ -554,16 +555,17 @@ static status_t select_and_install(private_child_create_t *this, } this->child_sa->set_proposal(this->child_sa, this->proposal); - if (!this->proposal->has_dh_group(this->proposal, this->dh_group)) + if (!this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { uint16_t group; - if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP, + if (this->proposal->get_algorithm(this->proposal, KEY_EXCHANGE_METHOD, &group, NULL)) { DBG1(DBG_IKE, "DH group %N unacceptable, requesting %N", - diffie_hellman_group_names, this->dh_group, - diffie_hellman_group_names, group); + key_exchange_method_names, this->dh_group, + key_exchange_method_names, group); this->dh_group = group; return INVALID_ARG; } @@ -571,7 +573,7 @@ static status_t select_and_install(private_child_create_t *this, DBG1(DBG_IKE, "ignoring KE exchange, agreed on a non-PFS proposal"); DESTROY_IF(this->dh); this->dh = NULL; - this->dh_group = MODP_NONE; + this->dh_group = KE_NONE; } if (this->initiator) @@ -713,13 +715,13 @@ static status_t select_and_install(private_child_create_t *this, { status_o = this->child_sa->register_outbound(this->child_sa, encr_i, integ_i, this->other_spi, this->other_cpi, - this->tfcv3); + this->initiator, this->tfcv3); } else { status_o = this->child_sa->register_outbound(this->child_sa, encr_r, integ_r, this->other_spi, this->other_cpi, - this->tfcv3); + this->initiator, this->tfcv3); } } else if (this->initiator) @@ -836,8 +838,8 @@ static bool build_payloads(private_child_create_t *this, message_t *message) /* diffie hellman exchange, if PFS enabled */ if (this->dh) { - ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, - this->dh); + ke_payload = ke_payload_create_from_key_exchange(PLV2_KEY_EXCHANGE, + this->dh); if (!ke_payload) { DBG1(DBG_IKE, "creating KE payload failed"); @@ -979,18 +981,19 @@ static void process_payloads(private_child_create_t *this, message_t *message) ke_payload = (ke_payload_t*)payload; if (!this->initiator) { - this->dh_group = ke_payload->get_dh_group_number(ke_payload); - this->dh = this->keymat->keymat.create_dh( + this->dh_group = ke_payload->get_key_exchange_method( + ke_payload); + this->dh = this->keymat->keymat.create_ke( &this->keymat->keymat, this->dh_group); } else if (this->dh) { - this->dh_failed = this->dh->get_dh_group(this->dh) != - ke_payload->get_dh_group_number(ke_payload); + this->dh_failed = this->dh->get_method(this->dh) != + ke_payload->get_key_exchange_method(ke_payload); } if (this->dh && !this->dh_failed) { - this->dh_failed = !this->dh->set_other_public_value(this->dh, + this->dh_failed = !this->dh->set_public_key(this->dh, ke_payload->get_key_exchange_data(ke_payload)); } break; @@ -1155,17 +1158,13 @@ METHOD(task_t, build_i, status_t, message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED); return SUCCESS; } - if (!this->retry && this->dh_group == MODP_NONE) + if (!this->retry && this->dh_group == KE_NONE) { /* during a rekeying the group might already be set */ - this->dh_group = this->config->get_dh_group(this->config); + this->dh_group = this->config->get_algorithm(this->config, + KEY_EXCHANGE_METHOD); } break; case IKE_AUTH: - if (message->get_message_id(message) != 1) - { - /* send only in the first request, not in subsequent rounds */ - return NEED_MORE; - } switch (defer_child_sa(this)) { case DESTROY_ME: @@ -1179,9 +1178,11 @@ METHOD(task_t, build_i, status_t, /* just continue to establish the CHILD_SA */ break; } + /* send only in the first request, not in subsequent rounds */ + this->public.task.build = (void*)return_need_more; break; default: - break; + return NEED_MORE; } /* check if we want a virtual IP, but don't have one */ @@ -1244,7 +1245,7 @@ METHOD(task_t, build_i, status_t, } this->proposals = this->config->get_proposals(this->config, - this->dh_group == MODP_NONE); + this->dh_group == KE_NONE); this->mode = this->config->get_mode(this->config); this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa, TRUE); @@ -1287,13 +1288,13 @@ METHOD(task_t, build_i, status_t, { DBG1(DBG_IKE, "requested DH group %N not contained in any of our " "proposals", - diffie_hellman_group_names, this->dh_group); + key_exchange_method_names, this->dh_group); return FAILED; } - if (this->dh_group != MODP_NONE) + if (this->dh_group != KE_NONE) { - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, + this->dh = this->keymat->keymat.create_ke(&this->keymat->keymat, this->dh_group); } @@ -1340,13 +1341,11 @@ METHOD(task_t, process_r, status_t, get_nonce(message, &this->other_nonce); break; case IKE_AUTH: - if (message->get_message_id(message) != 1) - { - /* only handle first AUTH payload, not additional rounds */ - return NEED_MORE; - } - default: + /* only handle first AUTH payload, not additional rounds */ + this->public.task.process = (void*)return_need_more; break; + default: + return NEED_MORE; } process_payloads(this, message); @@ -1575,8 +1574,9 @@ METHOD(task_t, build_r, status_t, break; } ike_auth = TRUE; - default: break; + default: + return NEED_MORE; } if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING) @@ -1772,8 +1772,9 @@ METHOD(task_t, process_i, status_t, return NEED_MORE; } ike_auth = TRUE; - default: break; + default: + return NEED_MORE; } /* check for erroneous notifies */ @@ -1818,7 +1819,7 @@ METHOD(task_t, process_i, status_t, case INVALID_KE_PAYLOAD: { chunk_t data; - uint16_t group = MODP_NONE; + uint16_t group = KE_NONE; data = notify->get_notification_data(notify); if (data.len == sizeof(group)) @@ -1829,15 +1830,15 @@ METHOD(task_t, process_i, status_t, if (this->retry) { DBG1(DBG_IKE, "already retried with DH group %N, " - "ignore requested %N", diffie_hellman_group_names, - this->dh_group, diffie_hellman_group_names, group); + "ignore requested %N", key_exchange_method_names, + this->dh_group, key_exchange_method_names, group); handle_child_sa_failure(this, message); /* an error in CHILD_SA creation is not critical */ return SUCCESS; } DBG1(DBG_IKE, "peer didn't accept DH group %N, " - "it requested %N", diffie_hellman_group_names, - this->dh_group, diffie_hellman_group_names, group); + "it requested %N", key_exchange_method_names, + this->dh_group, key_exchange_method_names, group); this->retry = TRUE; this->dh_group = group; this->child_sa->set_state(this->child_sa, CHILD_RETRYING); @@ -1945,7 +1946,7 @@ METHOD(child_create_t, use_label, void, } METHOD(child_create_t, use_dh_group, void, - private_child_create_t *this, diffie_hellman_group_t dh_group) + private_child_create_t *this, key_exchange_method_t dh_group) { this->dh_group = dh_group; } @@ -2015,7 +2016,7 @@ METHOD(task_t, migrate, void, } if (!this->rekey && !this->retry) { - this->dh_group = MODP_NONE; + this->dh_group = KE_NONE; } this->ike_sa = ike_sa; this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa); @@ -2031,6 +2032,7 @@ METHOD(task_t, migrate, void, this->ipcomp_received = IPCOMP_NONE; this->other_cpi = 0; this->established = FALSE; + this->public.task.build = _build_i; } METHOD(task_t, destroy, void, @@ -2101,7 +2103,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, .config = config, .packet_tsi = tsi ? tsi->clone(tsi) : NULL, .packet_tsr = tsr ? tsr->clone(tsr) : NULL, - .dh_group = MODP_NONE, + .dh_group = KE_NONE, .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa), .mode = MODE_TUNNEL, .tfcv3 = TRUE, diff --git a/src/libcharon/sa/ikev2/tasks/child_create.h b/src/libcharon/sa/ikev2/tasks/child_create.h index b27f2cbe5..705b7e116 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.h +++ b/src/libcharon/sa/ikev2/tasks/child_create.h @@ -83,7 +83,7 @@ struct child_create_t { * * @param dh_group DH group to use */ - void (*use_dh_group)(child_create_t *this, diffie_hellman_group_t dh_group); + void (*use_dh_group)(child_create_t *this, key_exchange_method_t dh_group); /** * Get the lower of the two nonces, used for rekey collisions. diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index dbbf62e91..9281c6339 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -197,7 +197,7 @@ METHOD(task_t, build_i, status_t, config->get_ref(config), TRUE, NULL, NULL); proposal = this->child_sa->get_proposal(this->child_sa); - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &dh_group, NULL)) { /* reuse the DH group negotiated previously */ this->child_create->use_dh_group(this->child_create, dh_group); @@ -528,7 +528,7 @@ METHOD(child_rekey_t, is_redundant, bool, return FALSE; } -METHOD(child_rekey_t, collide, void, +METHOD(child_rekey_t, collide, bool, private_child_rekey_t *this, task_t *other) { /* the task manager only detects exchange collision, but not if @@ -540,16 +540,14 @@ METHOD(child_rekey_t, collide, void, if (rekey->child_sa != this->child_sa) { /* not the same child => no collision */ - other->destroy(other); - return; + return FALSE; } /* ignore passive tasks that did not successfully create a CHILD_SA */ other_child = rekey->child_create->get_child(rekey->child_create); if (!other_child || other_child->get_state(other_child) != CHILD_INSTALLED) { - other->destroy(other); - return; + return FALSE; } } else if (other->get_type(other) == TASK_CHILD_DELETE) @@ -558,26 +556,24 @@ METHOD(child_rekey_t, collide, void, if (is_redundant(this, del->get_child(del))) { this->other_child_destroyed = TRUE; - other->destroy(other); - return; + return FALSE; } if (del->get_child(del) != this->child_sa) { /* not the same child => no collision */ - other->destroy(other); - return; + return FALSE; } } else { - /* any other task is not critical for collisions, ignore */ - other->destroy(other); - return; + /* shouldn't happen */ + return FALSE; } DBG1(DBG_IKE, "detected %N collision with %N", task_type_names, TASK_CHILD_REKEY, task_type_names, other->get_type(other)); DESTROY_IF(this->collision); this->collision = other; + return TRUE; } METHOD(task_t, migrate, void, diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.h b/src/libcharon/sa/ikev2/tasks/child_rekey.h index 4b584274e..849df3a2b 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.h +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2020 Tobias Brunner * Copyright (C) 2007 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -59,9 +59,11 @@ struct child_rekey_t { * be handled gracefully. The task manager is aware of what exchanges * are going on and notifies the active task by passing the passive. * - * @param other passive task (adopted) + * @param other passive task + * @return whether the task was adopted and should be removed from + * the task manager's control */ - void (*collide)(child_rekey_t* this, task_t *other); + bool (*collide)(child_rekey_t* this, task_t *other); }; /** diff --git a/src/libcharon/sa/ikev2/tasks/ike_auth.c b/src/libcharon/sa/ikev2/tasks/ike_auth.c index 9e61ca707..ec887b9c7 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_auth.c +++ b/src/libcharon/sa/ikev2/tasks/ike_auth.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2018 Tobias Brunner + * Copyright (C) 2012-2019 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * @@ -131,6 +131,11 @@ struct private_ike_auth_t { */ bool eap_acceptable; + /** + * Whether we already handled the first IKE_AUTH message + */ + bool first_auth; + /** * Gateway ID if redirected */ @@ -154,20 +159,15 @@ static status_t collect_my_init_data(private_ike_auth_t *this, { nonce_payload_t *nonce; - /* get the nonce that was generated in ike_init */ + /* get the nonce that was generated in ike_init and a copy of the complete + * packet */ nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE); - if (!nonce) + if (!nonce || !message->is_encoded(message)) { return FAILED; } this->my_nonce = nonce->get_nonce(nonce); - - /* pre-generate the message, keep a copy */ - if (this->ike_sa->generate_message(this->ike_sa, message, - &this->my_packet) != SUCCESS) - { - return FAILED; - } + this->my_packet = message->get_packet(message); return NEED_MORE; } @@ -588,10 +588,18 @@ METHOD(task_t, build_i, status_t, private_ike_auth_t *this, message_t *message) { auth_cfg_t *cfg; + bool first_auth = FALSE; - if (message->get_exchange_type(message) == IKE_SA_INIT) + switch (message->get_exchange_type(message)) { - return collect_my_init_data(this, message); + case IKE_AUTH: + if (!this->first_auth) + { /* some special handling for the first IKE_AUTH message below */ + first_auth = this->first_auth = TRUE; + } + break; + default: + return NEED_MORE; } if (!this->peer_cfg) @@ -600,7 +608,7 @@ METHOD(task_t, build_i, status_t, this->peer_cfg->get_ref(this->peer_cfg); } - if (message->get_message_id(message) == 1) + if (first_auth) { /* in the first IKE_AUTH ... */ if (this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH)) { /* indicate support for multiple authentication */ @@ -668,8 +676,7 @@ METHOD(task_t, build_i, status_t, get_reserved_id_bytes(this, id_payload); message->add_payload(message, (payload_t*)id_payload); - if (idr && !idr->contains_wildcards(idr) && - message->get_message_id(message) == 1 && + if (idr && !idr->contains_wildcards(idr) && first_auth && this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER) { host_t *host; @@ -737,6 +744,18 @@ METHOD(task_t, build_i, status_t, return NEED_MORE; } +METHOD(task_t, post_build_i, status_t, + private_ike_auth_t *this, message_t *message) +{ + switch (message->get_exchange_type(message)) + { + case IKE_SA_INIT: + return collect_my_init_data(this, message); + default: + return NEED_MORE; + } +} + METHOD(task_t, process_r, status_t, private_ike_auth_t *this, message_t *message) { @@ -744,9 +763,14 @@ METHOD(task_t, process_r, status_t, id_payload_t *id_payload; identification_t *id; - if (message->get_exchange_type(message) == IKE_SA_INIT) + switch (message->get_exchange_type(message)) { - return collect_other_init_data(this, message); + case IKE_SA_INIT: + return collect_other_init_data(this, message); + case IKE_AUTH: + break; + default: + return NEED_MORE; } if (!this->my_auth && this->do_another_auth) @@ -769,7 +793,7 @@ METHOD(task_t, process_r, status_t, return NEED_MORE; } - if (message->get_message_id(message) == 1) + if (!this->first_auth) { /* check for extensions in the first IKE_AUTH */ if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED)) { @@ -784,6 +808,7 @@ METHOD(task_t, process_r, status_t, { this->initial_contact = TRUE; } + this->first_auth = TRUE; } if (!this->other_auth) @@ -950,14 +975,19 @@ METHOD(task_t, build_r, status_t, identification_t *gateway; auth_cfg_t *cfg; - if (message->get_exchange_type(message) == IKE_SA_INIT) + switch (message->get_exchange_type(message)) { - if (multiple_auth_enabled()) - { - message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED, - chunk_empty); - } - return collect_my_init_data(this, message); + case IKE_SA_INIT: + if (multiple_auth_enabled()) + { + message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED, + chunk_empty); + } + return NEED_MORE; + case IKE_AUTH: + break; + default: + return NEED_MORE; } if (this->authentication_failed || !this->peer_cfg) @@ -1159,6 +1189,18 @@ local_auth_failed: return FAILED; } +METHOD(task_t, post_build_r, status_t, + private_ike_auth_t *this, message_t *message) +{ + switch (message->get_exchange_type(message)) + { + case IKE_SA_INIT: + return collect_my_init_data(this, message); + default: + return NEED_MORE; + } +} + /** * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA */ @@ -1225,14 +1267,19 @@ METHOD(task_t, process_i, status_t, auth_cfg_t *cfg; bool mutual_eap = FALSE, ppk_id_received = FALSE; - if (message->get_exchange_type(message) == IKE_SA_INIT) + switch (message->get_exchange_type(message)) { - if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) && - multiple_auth_enabled()) - { - this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH); - } - return collect_other_init_data(this, message); + case IKE_SA_INIT: + if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) && + multiple_auth_enabled()) + { + this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH); + } + return collect_other_init_data(this, message); + case IKE_AUTH: + break; + default: + return NEED_MORE; } enumerator = message->create_payload_enumerator(message); @@ -1514,6 +1561,7 @@ METHOD(task_t, migrate, void, this->expect_another_auth = TRUE; this->authentication_failed = FALSE; this->candidates = linked_list_create(); + this->first_auth = FALSE; } METHOD(task_t, destroy, void, @@ -1545,6 +1593,7 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator) .get_type = _get_type, .migrate = _migrate, .build = _build_r, + .post_build = _post_build_r, .process = _process_r, .destroy = _destroy, }, @@ -1558,6 +1607,7 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator) if (initiator) { this->public.task.build = _build_i; + this->public.task.post_build = _post_build_i; this->public.task.process = _process_i; } return &this->public; diff --git a/src/libcharon/sa/ikev2/tasks/ike_cert_post.c b/src/libcharon/sa/ikev2/tasks/ike_cert_post.c index 3c4be6e73..3f821842f 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_cert_post.c +++ b/src/libcharon/sa/ikev2/tasks/ike_cert_post.c @@ -255,8 +255,10 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message) METHOD(task_t, build_i, status_t, private_ike_cert_post_t *this, message_t *message) { - build_certs(this, message); - + if (message->get_exchange_type(message) == IKE_AUTH) + { + build_certs(this, message); + } return NEED_MORE; } @@ -269,8 +271,10 @@ METHOD(task_t, process_r, status_t, METHOD(task_t, build_r, status_t, private_ike_cert_post_t *this, message_t *message) { - build_certs(this, message); - + if (message->get_exchange_type(message) == IKE_AUTH) + { + build_certs(this, message); + } if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED) { /* stay alive, we might have additional rounds with certs */ return NEED_MORE; diff --git a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c index 9fb0bcf90..96d4477bb 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c +++ b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2018 Tobias Brunner * Copyright (C) 2006-2009 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -50,11 +50,6 @@ struct private_ike_cert_pre_t { * Do we accept HTTP certificate lookup requests */ bool do_http_lookup; - - /** - * whether this is the final authentication round - */ - bool final; }; /** @@ -469,24 +464,17 @@ static void build_certreqs(private_ike_cert_pre_t *this, message_t *message) */ static bool final_auth(message_t *message) { - /* we check for an AUTH payload without a ANOTHER_AUTH_FOLLOWS notify */ - if (message->get_payload(message, PLV2_AUTH) == NULL) - { - return FALSE; - } - if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS)) - { - return FALSE; - } - return TRUE; + return message->get_payload(message, PLV2_AUTH) != NULL && + !message->get_notify(message, ANOTHER_AUTH_FOLLOWS); } METHOD(task_t, build_i, status_t, private_ike_cert_pre_t *this, message_t *message) { - if (message->get_message_id(message) == 1) - { /* initiator sends CERTREQs in first IKE_AUTH */ + if (message->get_exchange_type(message) == IKE_AUTH) + { /* initiator sends CERTREQs in first IKE_AUTH only */ build_certreqs(this, message); + this->public.task.build = (void*)return_need_more; } return NEED_MORE; } @@ -494,12 +482,15 @@ METHOD(task_t, build_i, status_t, METHOD(task_t, process_r, status_t, private_ike_cert_pre_t *this, message_t *message) { - if (message->get_exchange_type(message) != IKE_SA_INIT) + if (message->get_exchange_type(message) == IKE_AUTH) { /* handle certreqs/certs in any IKE_AUTH, just in case */ process_certreqs(this, message); process_certs(this, message); + if (final_auth(message)) + { + return SUCCESS; + } } - this->final = final_auth(message); return NEED_MORE; } @@ -510,25 +501,26 @@ METHOD(task_t, build_r, status_t, { build_certreqs(this, message); } - if (this->final) - { - return SUCCESS; - } return NEED_MORE; } METHOD(task_t, process_i, status_t, private_ike_cert_pre_t *this, message_t *message) { - if (message->get_exchange_type(message) == IKE_SA_INIT) + switch (message->get_exchange_type(message)) { - process_certreqs(this, message); - } - process_certs(this, message); - - if (final_auth(message)) - { - return SUCCESS; + case IKE_SA_INIT: + process_certreqs(this, message); + break; + case IKE_AUTH: + process_certs(this, message); + if (final_auth(message)) + { + return SUCCESS; + } + break; + default: + break; } return NEED_MORE; } @@ -543,6 +535,7 @@ METHOD(task_t, migrate, void, private_ike_cert_pre_t *this, ike_sa_t *ike_sa) { this->ike_sa = ike_sa; + this->public.task.build = _build_i; } METHOD(task_t, destroy, void, diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c index 9cba9aeac..221bc0d20 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_config.c +++ b/src/libcharon/sa/ikev2/tasks/ike_config.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012-2018 Tobias Brunner * Copyright (C) 2007 Martin Willi * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser * @@ -240,8 +241,8 @@ static void process_payloads(private_ike_config_t *this, message_t *message) METHOD(task_t, build_i, status_t, private_ike_config_t *this, message_t *message) { - if (message->get_message_id(message) == 1) - { /* in first IKE_AUTH only */ + if (message->get_exchange_type(message) == IKE_AUTH) + { cp_payload_t *cp = NULL; enumerator_t *enumerator; attribute_handler_t *handler; @@ -251,6 +252,10 @@ METHOD(task_t, build_i, status_t, linked_list_t *vips; host_t *host; + /* add attributes to first IKE_AUTH only, keep registered until + * attributes are received in the last IKE_AUTH */ + this->public.task.build = (void*)return_need_more; + vips = linked_list_create(); /* reuse virtual IP if we already have one */ @@ -329,9 +334,11 @@ METHOD(task_t, build_i, status_t, METHOD(task_t, process_r, status_t, private_ike_config_t *this, message_t *message) { - if (message->get_message_id(message) == 1) - { /* in first IKE_AUTH only */ + if (message->get_exchange_type(message) == IKE_AUTH) + { process_payloads(this, message); + /* process attributes in first IKE_AUTH only */ + this->public.task.process = (void*)return_need_more; } return NEED_MORE; } @@ -486,6 +493,7 @@ METHOD(task_t, migrate, void, this->vips = linked_list_create(); this->requested->destroy_function(this->requested, free); this->requested = linked_list_create(); + this->public.task.build = _build_i; } METHOD(task_t, destroy, void, diff --git a/src/libcharon/sa/ikev2/tasks/ike_delete.c b/src/libcharon/sa/ikev2/tasks/ike_delete.c index 00235c53d..aa9c01734 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_delete.c +++ b/src/libcharon/sa/ikev2/tasks/ike_delete.c @@ -65,9 +65,8 @@ METHOD(task_t, build_i, status_t, delete_payload = delete_payload_create(PLV2_DELETE, PROTO_IKE); message->add_payload(message, (payload_t*)delete_payload); - if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING || - this->ike_sa->get_state(this->ike_sa) == IKE_REKEYED) - { + if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYED) + { /* suppress events when deleting old or redundant SAs */ this->rekeyed = TRUE; } this->ike_sa->set_state(this->ike_sa, IKE_DELETING); diff --git a/src/libcharon/sa/ikev2/tasks/ike_dpd.c b/src/libcharon/sa/ikev2/tasks/ike_dpd.c index 7a446c962..724670cc8 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_dpd.c +++ b/src/libcharon/sa/ikev2/tasks/ike_dpd.c @@ -32,12 +32,6 @@ struct private_ike_dpd_t { ike_dpd_t public; }; -METHOD(task_t, return_need_more, status_t, - private_ike_dpd_t *this, message_t *message) -{ - return NEED_MORE; -} - METHOD(task_t, get_type, task_type_t, private_ike_dpd_t *this) { @@ -48,7 +42,6 @@ METHOD(task_t, get_type, task_type_t, METHOD(task_t, migrate, void, private_ike_dpd_t *this, ike_sa_t *ike_sa) { - } METHOD(task_t, destroy, void, @@ -76,13 +69,13 @@ ike_dpd_t *ike_dpd_create(bool initiator) if (initiator) { - this->public.task.build = _return_need_more; + this->public.task.build = (void*)return_need_more; this->public.task.process = (void*)return_success; } else { this->public.task.build = (void*)return_success; - this->public.task.process = _return_need_more; + this->public.task.process = (void*)return_need_more; } return &this->public; diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 3adb3d42f..a73c98ac9 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -55,15 +55,25 @@ struct private_ike_init_t { */ bool initiator; + /** + * Whether the key exchange is done + */ + bool ke_done; + + /** + * Whether keys have already been derived + */ + bool ke_derived; + /** * diffie hellman group to use */ - diffie_hellman_group_t dh_group; + key_exchange_method_t dh_group; /** * diffie hellman key exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Applying DH public value failed? @@ -333,7 +343,8 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) proposal->set_spi(proposal, id->get_initiator_spi(id)); } /* move the selected DH group to the front of the proposal */ - if (!proposal->promote_dh_group(proposal, this->dh_group)) + if (!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { /* the proposal does not include the group, move to the back */ proposal_list->remove_at(proposal_list, enumerator); other_dh_groups->insert_last(other_dh_groups, proposal); @@ -363,8 +374,8 @@ static bool build_payloads(private_ike_init_t *this, message_t *message) } message->add_payload(message, (payload_t*)sa_payload); - ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, - this->dh); + ke_payload = ke_payload_create_from_key_exchange(PLV2_KEY_EXCHANGE, + this->dh); if (!ke_payload) { DBG1(DBG_IKE, "creating KE payload failed"); @@ -519,6 +530,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { enumerator_t *enumerator; payload_t *payload; + ike_sa_id_t *id; ke_payload_t *ke_payload = NULL; enumerator = message->create_payload_enumerator(message); @@ -535,7 +547,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { ke_payload = (ke_payload_t*)payload; - this->dh_group = ke_payload->get_dh_group_number(ke_payload); + this->dh_group = ke_payload->get_key_exchange_method(ke_payload); break; } case PLV2_NONCE: @@ -614,23 +626,39 @@ static void process_payloads(private_ike_init_t *this, message_t *message) if (this->proposal) { this->ike_sa->set_proposal(this->ike_sa, this->proposal); + + if (this->old_sa) + { /* retrieve SPI of new IKE_SA when rekeying */ + id = this->ike_sa->get_id(this->ike_sa); + if (this->initiator) + { + id->set_responder_spi(id, + this->proposal->get_spi(this->proposal)); + } + else + { + id->set_initiator_spi(id, + this->proposal->get_spi(this->proposal)); + } + } } if (ke_payload && this->proposal && - this->proposal->has_dh_group(this->proposal, this->dh_group)) + this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { if (!this->initiator) { - this->dh = this->keymat->keymat.create_dh( + this->dh = this->keymat->keymat.create_ke( &this->keymat->keymat, this->dh_group); } else if (this->dh) { - this->dh_failed = this->dh->get_dh_group(this->dh) != this->dh_group; + this->dh_failed = this->dh->get_method(this->dh) != this->dh_group; } if (this->dh && !this->dh_failed) { - this->dh_failed = !this->dh->set_other_public_value(this->dh, + this->dh_failed = !this->dh->set_public_key(this->dh, ke_payload->get_key_exchange_data(ke_payload)); } } @@ -665,38 +693,40 @@ METHOD(task_t, build_i, status_t, uint16_t dh_group; proposal = this->old_sa->get_proposal(this->old_sa); - if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, + if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &dh_group, NULL)) { this->dh_group = dh_group; } else { /* this shouldn't happen, but let's be safe */ - this->dh_group = ike_cfg->get_dh_group(ike_cfg); + this->dh_group = ike_cfg->get_algorithm(ike_cfg, + KEY_EXCHANGE_METHOD); } } else { - this->dh_group = ike_cfg->get_dh_group(ike_cfg); + this->dh_group = ike_cfg->get_algorithm(ike_cfg, + KEY_EXCHANGE_METHOD); } - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, + this->dh = this->keymat->keymat.create_ke(&this->keymat->keymat, this->dh_group); if (!this->dh) { DBG1(DBG_IKE, "configured DH group %N not supported", - diffie_hellman_group_names, this->dh_group); + key_exchange_method_names, this->dh_group); return FAILED; } } - else if (this->dh->get_dh_group(this->dh) != this->dh_group) + else if (this->dh->get_method(this->dh) != this->dh_group) { /* reset DH instance if group changed (INVALID_KE_PAYLOAD) */ this->dh->destroy(this->dh); - this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat, + this->dh = this->keymat->keymat.create_ke(&this->keymat->keymat, this->dh_group); if (!this->dh) { DBG1(DBG_IKE, "requested DH group %N not supported", - diffie_hellman_group_names, this->dh_group); + key_exchange_method_names, this->dh_group); return FAILED; } } @@ -765,8 +795,8 @@ METHOD(task_t, process_r, status_t, /** * Derive the keymat for the IKE_SA */ -static bool derive_keys(private_ike_init_t *this, - chunk_t nonce_i, chunk_t nonce_r) +static bool derive_keys_internal(private_ike_init_t *this, chunk_t nonce_i, + chunk_t nonce_r) { keymat_v2_t *old_keymat; pseudo_random_function_t prf_alg = PRF_UNDEFINED; @@ -779,14 +809,6 @@ static bool derive_keys(private_ike_init_t *this, /* rekeying: Include old SKd, use old PRF, apply SPI */ old_keymat = (keymat_v2_t*)this->old_sa->get_keymat(this->old_sa); prf_alg = old_keymat->get_skd(old_keymat, &skd); - if (this->initiator) - { - id->set_responder_spi(id, this->proposal->get_spi(this->proposal)); - } - else - { - id->set_initiator_spi(id, this->proposal->get_spi(this->proposal)); - } } if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh, nonce_i, nonce_r, id, prf_alg, skd)) @@ -798,6 +820,35 @@ static bool derive_keys(private_ike_init_t *this, return TRUE; } +METHOD(ike_init_t, derive_keys, status_t, + private_ike_init_t *this) +{ + bool success; + + if (!this->ke_done || this->ke_derived) + { + return NEED_MORE; + } + + if (this->initiator) + { + success = derive_keys_internal(this, this->my_nonce, this->other_nonce); + } + else + { + success = derive_keys_internal(this, this->other_nonce, this->my_nonce); + } + + this->ke_derived = TRUE; + + if (!success) + { + DBG1(DBG_IKE, "key derivation failed"); + return FAILED; + } + return SUCCESS; +} + METHOD(task_t, build_r, status_t, private_ike_init_t *this, message_t *message) { @@ -829,16 +880,17 @@ METHOD(task_t, build_r, status_t, } if (this->dh == NULL || - !this->proposal->has_dh_group(this->proposal, this->dh_group)) + !this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { uint16_t group; - if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP, + if (this->proposal->get_algorithm(this->proposal, KEY_EXCHANGE_METHOD, &group, NULL)) { DBG1(DBG_IKE, "DH group %N unacceptable, requesting %N", - diffie_hellman_group_names, this->dh_group, - diffie_hellman_group_names, group); + key_exchange_method_names, this->dh_group, + key_exchange_method_names, group); this->dh_group = group; group = htons(group); message->add_notify(message, FALSE, INVALID_KE_PAYLOAD, @@ -859,18 +911,25 @@ METHOD(task_t, build_r, status_t, return FAILED; } - if (!derive_keys(this, this->other_nonce, this->my_nonce)) - { - DBG1(DBG_IKE, "key derivation failed"); - message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); - return FAILED; - } if (!build_payloads(this, message)) { message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); return FAILED; } - return SUCCESS; + this->ke_done = TRUE; + + if (this->old_sa) + { + /* during rekeying, we derive keys here directly */ + if (derive_keys(this) != SUCCESS) + { + message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty); + return FAILED; + } + return SUCCESS; + } + /* key derivation is done before the next request is processed */ + return NEED_MORE; } /** @@ -976,14 +1035,14 @@ METHOD(task_t, process_i, status_t, case INVALID_KE_PAYLOAD: { chunk_t data; - diffie_hellman_group_t bad_group; + key_exchange_method_t bad_group; bad_group = this->dh_group; data = notify->get_notification_data(notify); this->dh_group = ntohs(*((uint16_t*)data.ptr)); DBG1(DBG_IKE, "peer didn't accept DH group %N, " - "it requested %N", diffie_hellman_group_names, - bad_group, diffie_hellman_group_names, this->dh_group); + "it requested %N", key_exchange_method_names, + bad_group, key_exchange_method_names, this->dh_group); if (this->old_sa == NULL) { /* reset the IKE_SA if we are not rekeying */ @@ -1003,6 +1062,12 @@ METHOD(task_t, process_i, status_t, break; case COOKIE: { + if (this->old_sa) + { + DBG1(DBG_IKE, "received COOKIE notify during rekeying" + ", ignored"); + break; + } chunk_free(&this->cookie); this->cookie = chunk_clone(notify->get_notification_data(notify)); this->ike_sa->reset(this->ike_sa, FALSE); @@ -1064,7 +1129,8 @@ METHOD(task_t, process_i, status_t, } if (this->dh == NULL || - !this->proposal->has_dh_group(this->proposal, this->dh_group)) + !this->proposal->has_transform(this->proposal, KEY_EXCHANGE_METHOD, + this->dh_group)) { DBG1(DBG_IKE, "peer DH group selection invalid"); return FAILED; @@ -1075,13 +1141,15 @@ METHOD(task_t, process_i, status_t, DBG1(DBG_IKE, "applying DH public value failed"); return FAILED; } + this->ke_done = TRUE; - if (!derive_keys(this, this->my_nonce, this->other_nonce)) + if (this->old_sa) { - DBG1(DBG_IKE, "key derivation failed"); - return FAILED; + /* during rekeying, we derive keys here directly */ + return derive_keys(this); } - return SUCCESS; + /* key derivation is done before we send the next message */ + return NEED_MORE; } METHOD(task_t, get_type, task_type_t, @@ -1095,6 +1163,8 @@ METHOD(task_t, migrate, void, { DESTROY_IF(this->proposal); chunk_free(&this->other_nonce); + this->ke_done = FALSE; + this->ke_derived = FALSE; this->ike_sa = ike_sa; this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa); @@ -1142,11 +1212,12 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) .migrate = _migrate, .destroy = _destroy, }, + .derive_keys = _derive_keys, .get_lower_nonce = _get_lower_nonce, }, .ike_sa = ike_sa, .initiator = initiator, - .dh_group = MODP_NONE, + .dh_group = KE_NONE, .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa), .old_sa = old_sa, .signature_authentication = lib->settings->get_bool(lib->settings, diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.h b/src/libcharon/sa/ikev2/tasks/ike_init.h index 6f2e47a6c..eea4e58e0 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.h +++ b/src/libcharon/sa/ikev2/tasks/ike_init.h @@ -40,6 +40,18 @@ struct ike_init_t { */ task_t task; + /** + * Derive the keys for this IKE_SA when not used during a rekeying. + * + * @return + * - FAILED if key derivation failed + * - NEED_MORE if key drivation was successful but more + * key exchanges are necessary + * - SUCCESS if key derivation was successful and the task + * can be removed from the queue + */ + status_t (*derive_keys)(ike_init_t *this); + /** * Get the lower of the two nonces, used for rekey collisions. * diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index ad47e6a22..5cfc72d78 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -366,11 +366,12 @@ METHOD(ike_mobike_t, transmit, bool, METHOD(task_t, build_i, status_t, private_ike_mobike_t *this, message_t *message) { - if (message->get_exchange_type(message) == IKE_AUTH && - message->get_message_id(message) == 1) - { /* only in first IKE_AUTH */ + if (message->get_exchange_type(message) == IKE_AUTH) + { message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty); build_address_list(this, message); + /* only in first IKE_AUTH */ + this->public.task.build = (void*)return_need_more; } else if (message->get_exchange_type(message) == INFORMATIONAL) { @@ -424,10 +425,11 @@ METHOD(task_t, build_i, status_t, METHOD(task_t, process_r, status_t, private_ike_mobike_t *this, message_t *message) { - if (message->get_exchange_type(message) == IKE_AUTH && - message->get_message_id(message) == 1) - { /* only first IKE_AUTH */ + if (message->get_exchange_type(message) == IKE_AUTH) + { process_payloads(this, message); + /* only first IKE_AUTH */ + this->public.task.process = (void*)return_need_more; } else if (message->get_exchange_type(message) == INFORMATIONAL) { @@ -473,7 +475,7 @@ METHOD(task_t, build_r, status_t, { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) - { + { /* in last IKE_AUTH only */ if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) { message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty); @@ -502,7 +504,7 @@ METHOD(task_t, process_i, status_t, { if (message->get_exchange_type(message) == IKE_AUTH && this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED) - { + { /* in last IKE_AUTH only */ process_payloads(this, message); return SUCCESS; } @@ -642,6 +644,7 @@ METHOD(task_t, migrate, void, { this->natd->task.migrate(&this->natd->task, ike_sa); } + this->public.task.build = _build_i; } METHOD(task_t, destroy, void, diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.c b/src/libcharon/sa/ikev2/tasks/ike_rekey.c index 1dc0fd6e8..85c47efc0 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2016 Tobias Brunner + * Copyright (C) 2015-2018 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * @@ -67,7 +67,7 @@ struct private_ike_rekey_t { /** * colliding task detected by the task manager */ - task_t *collision; + private_ike_rekey_t *collision; /** * TRUE if rekeying can't be handled temporarily @@ -167,8 +167,16 @@ METHOD(task_t, build_i, status_t, ike_version_t version; /* create new SA only on first try */ - if (this->new_sa == NULL) + if (!this->new_sa) { + if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING || + this->ike_sa->get_state(this->ike_sa) == IKE_REKEYED) + { + /* ignore SAs that have or are currently being rekeyed passively */ + message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED); + return SUCCESS; + } + version = this->ike_sa->get_version(this->ike_sa); this->new_sa = charon->ike_sa_manager->create_new( charon->ike_sa_manager, version, TRUE); @@ -254,7 +262,7 @@ METHOD(task_t, process_r, status_t, this->new_sa->inherit_pre(this->new_sa, this->ike_sa); this->ike_init = ike_init_create(this->new_sa, FALSE, this->ike_sa); this->ike_init->task.process(&this->ike_init->task, message); - + charon->bus->set_sa(charon->bus, this->ike_sa); return NEED_MORE; } @@ -266,12 +274,14 @@ METHOD(task_t, build_r, status_t, message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty); return SUCCESS; } - if (this->new_sa == NULL) + if (!this->new_sa) { /* IKE_SA/a CHILD_SA is in an unacceptable state, deny rekeying */ message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); return SUCCESS; } + + charon->bus->set_sa(charon->bus, this->new_sa); if (this->ike_init->task.build(&this->ike_init->task, message) == FAILED) { this->ike_init->task.destroy(&this->ike_init->task); @@ -303,12 +313,11 @@ METHOD(task_t, build_r, status_t, */ static bool conclude_undetected_collision(private_ike_rekey_t *this) { - if (this->collision && - this->collision->get_type(this->collision) == TASK_IKE_REKEY) + if (this->collision) { DBG1(DBG_IKE, "peer did not notice IKE_SA rekey collision, abort " "active rekeying"); - establish_new((private_ike_rekey_t*)this->collision); + establish_new(this->collision); return TRUE; } return FALSE; @@ -338,26 +347,24 @@ METHOD(task_t, process_i, status_t, } return SUCCESS; case NEED_MORE: - /* bad dh group, try again */ + /* bad KE method, try again */ this->ike_init->task.migrate(&this->ike_init->task, this->new_sa); return NEED_MORE; default: break; } - /* check for collisions */ - if (this->collision && - this->collision->get_type(this->collision) == TASK_IKE_REKEY) + if (this->collision) { - private_ike_rekey_t *other = (private_ike_rekey_t*)this->collision; + private_ike_rekey_t *other = this->collision; host_t *host; chunk_t this_nonce, other_nonce; this_nonce = this->ike_init->get_lower_nonce(this->ike_init); other_nonce = other->ike_init->get_lower_nonce(other->ike_init); - /* if we have the lower nonce, delete rekeyed SA. If not, delete - * the redundant. */ + /* the SA with the lowest nonce should be deleted, check if we or + * the peer created that */ if (memcmp(this_nonce.ptr, other_nonce.ptr, min(this_nonce.len, other_nonce.len)) < 0) { @@ -369,9 +376,7 @@ METHOD(task_t, process_i, status_t, this->new_sa->set_my_host(this->new_sa, host->clone(host)); host = this->ike_sa->get_other_host(this->ike_sa); this->new_sa->set_other_host(this->new_sa, host->clone(host)); - /* IKE_SAs in state IKE_REKEYED are silently deleted, so we use - * IKE_REKEYING */ - this->new_sa->set_state(this->new_sa, IKE_REKEYING); + this->new_sa->set_state(this->new_sa, IKE_REKEYED); if (this->new_sa->delete(this->new_sa, FALSE) == DESTROY_ME) { this->new_sa->destroy(this->new_sa); @@ -386,7 +391,8 @@ METHOD(task_t, process_i, status_t, establish_new(other); return SUCCESS; } - /* peer should delete this SA. Add a timeout just in case. */ + + /* peer should delete the SA it created, add a timeout just in case */ job_t *job = (job_t*)delete_ike_sa_job_create( other->new_sa->get_id(other->new_sa), TRUE); lib->scheduler->schedule_job(lib->scheduler, job, @@ -402,7 +408,7 @@ METHOD(task_t, process_i, status_t, establish_new(this); - /* rekeying successful, delete the IKE_SA using a subtask */ + /* rekeying successful, delete this IKE_SA using a subtask */ this->ike_delete = ike_delete_create(this->ike_sa, TRUE); this->public.task.build = _build_i_delete; this->public.task.process = _process_i_delete; @@ -419,11 +425,10 @@ METHOD(task_t, get_type, task_type_t, METHOD(ike_rekey_t, did_collide, bool, private_ike_rekey_t *this) { - return this->collision && - this->collision->get_type(this->collision) == TASK_IKE_REKEY; + return this->collision != NULL; } -METHOD(ike_rekey_t, collide, void, +METHOD(ike_rekey_t, collide, bool, private_ike_rekey_t* this, task_t *other) { DBG1(DBG_IKE, "detected %N collision with %N", task_type_names, @@ -433,8 +438,7 @@ METHOD(ike_rekey_t, collide, void, { case TASK_IKE_DELETE: conclude_undetected_collision(this); - other->destroy(other); - return; + break; case TASK_IKE_REKEY: { private_ike_rekey_t *rekey = (private_ike_rekey_t*)other; @@ -443,16 +447,17 @@ METHOD(ike_rekey_t, collide, void, { DBG1(DBG_IKE, "colliding exchange did not result in an IKE_SA, " "ignore"); - other->destroy(other); - return; + break; } - break; + DESTROY_IF(&this->collision->public.task); + this->collision = rekey; + return TRUE; } default: + /* shouldn't happen */ break; } - DESTROY_IF(this->collision); - this->collision = other; + return FALSE; } /** @@ -473,7 +478,7 @@ static void cleanup(private_ike_rekey_t *this) cur_sa = charon->bus->get_sa(charon->bus); DESTROY_IF(this->new_sa); charon->bus->set_sa(charon->bus, cur_sa); - DESTROY_IF(this->collision); + DESTROY_IF(&this->collision->public.task); } METHOD(task_t, migrate, void, diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.h b/src/libcharon/sa/ikev2/tasks/ike_rekey.h index 30f9919db..5fab3491c 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_rekey.h +++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2020 Tobias Brunner * Copyright (C) 2007 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -47,15 +47,17 @@ struct ike_rekey_t { bool (*did_collide)(ike_rekey_t *this); /** - * Register a rekeying task which collides with this one. + * Register a rekeying/delete task which collides with this one. * * If two peers initiate rekeying at the same time, the collision must * be handled gracefully. The task manager is aware of what exchanges - * are going on and notifies the outgoing task by passing the incoming. + * are going on and notifies the active task by passing the passive. * - * @param other incoming task + * @param other passive task + * @return whether the task was adopted and should be removed from + * the task manager's control */ - void (*collide)(ike_rekey_t* this, task_t *other); + bool (*collide)(ike_rekey_t* this, task_t *other); }; /** diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h index 9e82fe2e1..34d7d7ee1 100644 --- a/src/libcharon/sa/keymat.h +++ b/src/libcharon/sa/keymat.h @@ -53,22 +53,21 @@ struct keymat_t { ike_version_t (*get_version)(keymat_t *this); /** - * Create a diffie hellman object for key agreement. + * Create a key exchange object for key agreement. * - * The diffie hellman is either for IKE negotiation/rekeying or - * CHILD_SA rekeying (using PFS). The resulting DH object must be passed - * to derive_keys or to derive_child_keys and destroyed after use. + * The key exchange is either for IKE negotiation/rekeying or + * CHILD_SA rekeying (using PFS). The resulting object must be passed + * to derive_ike_keys() or to derive_child_keys() and destroyed after use. * - * Only DH objects allocated through this method are passed to other - * keymat_t methods, allowing private DH implementations. In some cases - * (such as retrying with a COOKIE), a DH object allocated from a different + * Only objects allocated through this method are passed to other + * keymat_t methods, allowing private KE implementations. In some cases + * (such as retrying with a COOKIE), a KE object allocated from a different * keymat_t instance may be passed to other methods. * - * @param group diffie hellman group - * @return DH object, NULL if group not supported + * @param method key exchange method + * @return key exchange object, NULL if method not supported */ - diffie_hellman_t* (*create_dh)(keymat_t *this, - diffie_hellman_group_t group); + key_exchange_t* (*create_ke)(keymat_t *this, key_exchange_method_t method); /** * Create a nonce generator object. diff --git a/src/libcharon/sa/task.h b/src/libcharon/sa/task.h index e71433646..cc53e4425 100644 --- a/src/libcharon/sa/task.h +++ b/src/libcharon/sa/task.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2015 Tobias Brunner + * Copyright (C) 2007-2019 Tobias Brunner * Copyright (C) 2006 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -147,6 +147,18 @@ struct task_t { */ status_t (*build) (task_t *this, message_t *message); + /** + * Called after a message has been built (optional to implement by tasks). + * + * @param message generated message, can't be modified anymore + * @return + * - SUCCESS if task completed + * - NEED_MORE if another call to build/process needed + * - Anything else will result in the destruction of + * the IKE_SA + */ + status_t (*post_build) (task_t *this, message_t *message); + /** * Process a request or response message for this task. * @@ -172,6 +184,18 @@ struct task_t { */ status_t (*pre_process) (task_t *this, message_t *message); + /** + * Called after a message has been processed (optional to implement). + * + * @param message processed message + * @return + * - SUCCESS if task completed + * - NEED_MORE if another call to build/process needed + * - Anything else will result in the destruction of + * the IKE_SA + */ + status_t (*post_process) (task_t *this, message_t *message); + /** * Get the type of the task implementation. */ diff --git a/src/libcharon/tests/suites/test_message_chapoly.c b/src/libcharon/tests/suites/test_message_chapoly.c index e79f527f1..871775221 100644 --- a/src/libcharon/tests/suites/test_message_chapoly.c +++ b/src/libcharon/tests/suites/test_message_chapoly.c @@ -74,7 +74,7 @@ START_TEST(test_chacha20poly1305) chunk_t chunk, exp; keymat_t keymat = { .get_version = _get_version, - .create_dh = (void*)return_null, + .create_ke = (void*)return_null, .create_nonce_gen = (void*)return_null, .get_aead = _get_aead, }; diff --git a/src/libcharon/tests/utils/exchange_test_helper.c b/src/libcharon/tests/utils/exchange_test_helper.c index ccdb9034c..8c57c8877 100644 --- a/src/libcharon/tests/utils/exchange_test_helper.c +++ b/src/libcharon/tests/utils/exchange_test_helper.c @@ -300,17 +300,33 @@ METHOD(exchange_test_helper_t, add_listener, void, */ static void initialize_logging() { - int level = LEVEL_SILENT; - char *verbosity; + char buf[BUF_LEN], *verbosity; + level_t level; + debug_t group; + + lib->settings->set_default_str(lib->settings, "%s.filelog.stderr.default", + "-1", lib->ns); verbosity = getenv("TESTS_VERBOSITY"); if (verbosity) { level = atoi(verbosity); + lib->settings->set_int(lib->settings, "%s.filelog.stderr.default", + level, lib->ns); + } + + for (group = 0; group < DBG_MAX; group++) + { + snprintf(buf, sizeof(buf), "TESTS_VERBOSITY_%s", + enum_to_name(debug_names, group)); + verbosity = getenv(buf); + if (verbosity) + { + level = atoi(verbosity); + lib->settings->set_int(lib->settings, "%s.filelog.stderr.%N", + level, lib->ns, debug_lower_names, group); + } } - lib->settings->set_int(lib->settings, "%s.filelog.stderr.default", - lib->settings->get_int(lib->settings, "%s.filelog.stderr.default", - level, lib->ns), lib->ns); lib->settings->set_bool(lib->settings, "%s.filelog.stderr.ike_name", TRUE, lib->ns); charon->load_loggers(charon); @@ -332,11 +348,11 @@ void exchange_test_helper_init(char *plugins) private_exchange_test_helper_t *this; private_backend_t *backend; plugin_feature_t features[] = { - PLUGIN_REGISTER(DH, mock_dh_create), + PLUGIN_REGISTER(KE, mock_dh_create), /* we only need to support a limited number of DH groups */ - PLUGIN_PROVIDE(DH, MODP_2048_BIT), - PLUGIN_PROVIDE(DH, MODP_3072_BIT), - PLUGIN_PROVIDE(DH, ECP_256_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), + PLUGIN_PROVIDE(KE, ECP_256_BIT), PLUGIN_REGISTER(NONCE_GEN, create_nonce_gen), PLUGIN_PROVIDE(NONCE_GEN), PLUGIN_DEPENDS(RNG, RNG_WEAK), diff --git a/src/libcharon/tests/utils/mock_dh.c b/src/libcharon/tests/utils/mock_dh.c index e171e36fb..e2499752c 100644 --- a/src/libcharon/tests/utils/mock_dh.c +++ b/src/libcharon/tests/utils/mock_dh.c @@ -34,41 +34,41 @@ struct private_diffie_hellman_t { /** * Public interface */ - diffie_hellman_t public; + key_exchange_t public; /** - * Instantiated DH group + * Instantiated key exchagne method */ - diffie_hellman_group_t group; + key_exchange_method_t method; }; -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_diffie_hellman_t *this, chunk_t *value) { *value = chunk_clone(mock_key); return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_diffie_hellman_t *this, chunk_t value) { return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_clone(mock_key); return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_diffie_hellman_t *this) { - return this->group; + return this->method; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_diffie_hellman_t *this) { free(this); @@ -77,19 +77,19 @@ METHOD(diffie_hellman_t, destroy, void, /** * See header */ -diffie_hellman_t *mock_dh_create(diffie_hellman_group_t group) +key_exchange_t *mock_dh_create(key_exchange_method_t method) { private_diffie_hellman_t *this; INIT(this, .public = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .get_method = _get_method, .destroy = _destroy, }, - .group = group, + .method = method, ); return &this->public; } diff --git a/src/libcharon/tests/utils/mock_dh.h b/src/libcharon/tests/utils/mock_dh.h index 7ec0b13fc..8b6d6d132 100644 --- a/src/libcharon/tests/utils/mock_dh.h +++ b/src/libcharon/tests/utils/mock_dh.h @@ -25,14 +25,14 @@ #ifndef MOCK_DH_H_ #define MOCK_DH_H_ -#include +#include /** - * Creates a diffie_hellman_t object. + * Creates a key_exchange_t object. * - * @param group Diffie Hellman group, supports MODP_NULL only + * @param method key_exchange method, supports MODP_NULL only * @return created object */ -diffie_hellman_t *mock_dh_create(diffie_hellman_group_t group); +key_exchange_t *mock_dh_create(key_exchange_method_t method); #endif /** MOCK_DH_H_ @}*/ diff --git a/src/libimcv/pts/pts.c b/src/libimcv/pts/pts.c index cd52aa928..742e45b5a 100644 --- a/src/libimcv/pts/pts.c +++ b/src/libimcv/pts/pts.c @@ -70,7 +70,7 @@ struct private_pts_t { /** * PTS Diffie-Hellman Secret */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * PTS Diffie-Hellman Initiator Nonce @@ -200,15 +200,15 @@ METHOD(pts_t, set_dh_hash_algorithm, void, METHOD(pts_t, create_dh_nonce, bool, private_pts_t *this, pts_dh_group_t group, int nonce_len) { - diffie_hellman_group_t dh_group; + key_exchange_method_t dh_group; chunk_t *nonce; rng_t *rng; dh_group = pts_dh_group_to_ike(group); DBG2(DBG_PTS, "selected PTS DH group is %N", - diffie_hellman_group_names, dh_group); + key_exchange_method_names, dh_group); DESTROY_IF(this->dh); - this->dh = lib->crypto->create_dh(lib->crypto, dh_group); + this->dh = lib->crypto->create_ke(lib->crypto, dh_group); rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); if (!rng) @@ -232,7 +232,7 @@ METHOD(pts_t, create_dh_nonce, bool, METHOD(pts_t, get_my_public_value, bool, private_pts_t *this, chunk_t *value, chunk_t *nonce) { - if (!this->dh->get_my_public_value(this->dh, value)) + if (!this->dh->get_public_key(this->dh, value)) { return FALSE; } @@ -243,7 +243,7 @@ METHOD(pts_t, get_my_public_value, bool, METHOD(pts_t, set_peer_public_value, bool, private_pts_t *this, chunk_t value, chunk_t nonce) { - if (!this->dh->set_other_public_value(this->dh, value)) + if (!this->dh->set_public_key(this->dh, value)) { return FALSE; } diff --git a/src/libimcv/pts/pts_dh_group.c b/src/libimcv/pts/pts_dh_group.c index a63ab4252..91b5f2bfe 100644 --- a/src/libimcv/pts/pts_dh_group.c +++ b/src/libimcv/pts/pts_dh_group.c @@ -24,44 +24,44 @@ bool pts_dh_group_probe(pts_dh_group_t *dh_groups, bool mandatory_dh_groups) { enumerator_t *enumerator; - diffie_hellman_group_t dh_group; + key_exchange_method_t dh_group; const char *plugin_name; char format1[] = " %s PTS DH group %N[%s] available"; char format2[] = " %s PTS DH group %N not available"; *dh_groups = PTS_DH_GROUP_NONE; - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + enumerator = lib->crypto->create_ke_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &dh_group, &plugin_name)) { if (dh_group == MODP_1024_BIT) { *dh_groups |= PTS_DH_GROUP_IKE2; - DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names, + DBG2(DBG_PTS, format1, "optional ", key_exchange_method_names, dh_group, plugin_name); } else if (dh_group == MODP_1536_BIT) { *dh_groups |= PTS_DH_GROUP_IKE5; - DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names, + DBG2(DBG_PTS, format1, "optional ", key_exchange_method_names, dh_group, plugin_name); } else if (dh_group == MODP_2048_BIT) { *dh_groups |= PTS_DH_GROUP_IKE14; - DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names, + DBG2(DBG_PTS, format1, "optional ", key_exchange_method_names, dh_group, plugin_name); } else if (dh_group == ECP_256_BIT) { *dh_groups |= PTS_DH_GROUP_IKE19; - DBG2(DBG_PTS, format1, "mandatory", diffie_hellman_group_names, + DBG2(DBG_PTS, format1, "mandatory", key_exchange_method_names, dh_group, plugin_name); } else if (dh_group == ECP_384_BIT) { *dh_groups |= PTS_DH_GROUP_IKE20; - DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names, + DBG2(DBG_PTS, format1, "optional ", key_exchange_method_names, dh_group, plugin_name); } } @@ -79,7 +79,7 @@ bool pts_dh_group_probe(pts_dh_group_t *dh_groups, bool mandatory_dh_groups) } if (mandatory_dh_groups) { - DBG1(DBG_PTS, format2, "mandatory", diffie_hellman_group_names, + DBG1(DBG_PTS, format2, "mandatory", key_exchange_method_names, ECP_256_BIT); return FALSE; } @@ -165,7 +165,7 @@ pts_dh_group_t pts_dh_group_select(pts_dh_group_t supported_dh_groups, /** * Described in header. */ -diffie_hellman_group_t pts_dh_group_to_ike(pts_dh_group_t dh_group) +key_exchange_method_t pts_dh_group_to_ike(pts_dh_group_t dh_group) { switch (dh_group) { @@ -180,6 +180,6 @@ diffie_hellman_group_t pts_dh_group_to_ike(pts_dh_group_t dh_group) case PTS_DH_GROUP_IKE20: return ECP_384_BIT; default: - return MODP_NONE; + return KE_NONE; } } diff --git a/src/libimcv/pts/pts_dh_group.h b/src/libimcv/pts/pts_dh_group.h index db7f6855b..68a17661f 100644 --- a/src/libimcv/pts/pts_dh_group.h +++ b/src/libimcv/pts/pts_dh_group.h @@ -23,7 +23,7 @@ #define PTS_DH_GROUP_H_ #include -#include +#include typedef enum pts_dh_group_t pts_dh_group_t; @@ -98,11 +98,11 @@ pts_dh_group_t pts_dh_group_select(pts_dh_group_t supported_groups, pts_dh_group_t offered_groups); /** - * Convert pts_dh_group_t to diffie_hellman_group_t + * Convert pts_dh_group_t to key_exchange_method_t * * @param dh_group PTS DH group type * @return IKE DH group type */ -diffie_hellman_group_t pts_dh_group_to_ike(pts_dh_group_t dh_group); +key_exchange_method_t pts_dh_group_to_ike(pts_dh_group_t dh_group); #endif /** PTS_DH_GROUP_H_ @}*/ diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index 2399d1a95..12f26f346 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -15,7 +15,7 @@ crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \ crypto/rngs/rng.c crypto/rngs/rng_tester.c \ crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ -crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ +crypto/key_exchange.c crypto/aead.c crypto/transform.c \ crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \ crypto/iv/iv_gen_null.c crypto/kdfs/kdf.c \ crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 12d3b17d2..f118c723a 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -13,7 +13,7 @@ crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \ crypto/rngs/rng.c crypto/rngs/rng_tester.c \ crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ -crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ +crypto/key_exchange.c crypto/aead.c crypto/transform.c \ crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \ crypto/iv/iv_gen_null.c crypto/kdfs/kdf.c \ crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \ @@ -79,7 +79,7 @@ crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \ crypto/rngs/rng.h crypto/rngs/rng_tester.h \ crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/nonce_gen.h \ crypto/signers/signer.h crypto/signers/mac_signer.h \ -crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ +crypto/crypto_factory.h crypto/crypto_tester.h crypto/key_exchange.h \ crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \ crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h crypto/iv/iv_gen_null.h \ crypto/xofs/xof.h crypto/xofs/xof_bitspender.h crypto/xofs/mgf1.h \ diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index dcabcefe0..a6b49da5f 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -56,7 +56,7 @@ struct entry_t { drbg_constructor_t create_drbg; rng_constructor_t create_rng; nonce_gen_constructor_t create_nonce_gen; - dh_constructor_t create_dh; + ke_constructor_t create_ke; void *create; }; }; @@ -124,9 +124,9 @@ struct private_crypto_factory_t { linked_list_t *nonce_gens; /** - * registered diffie hellman, as entry_t + * registered key exchange methods, as entry_t */ - linked_list_t *dhs; + linked_list_t *kes; /** * test manager to test crypto algorithms @@ -484,37 +484,33 @@ METHOD(crypto_factory_t, create_nonce_gen, nonce_gen_t*, return nonce_gen; } -METHOD(crypto_factory_t, create_dh, diffie_hellman_t*, - private_crypto_factory_t *this, diffie_hellman_group_t group, ...) +METHOD(crypto_factory_t, create_ke, key_exchange_t*, + private_crypto_factory_t *this, key_exchange_method_t method, ...) { enumerator_t *enumerator; entry_t *entry; - va_list args; chunk_t g = chunk_empty, p = chunk_empty; - diffie_hellman_t *diffie_hellman = NULL; + key_exchange_t *ke = NULL; - if (group == MODP_CUSTOM) + if (method == MODP_CUSTOM) { - va_start(args, group); - g = va_arg(args, chunk_t); - p = va_arg(args, chunk_t); - va_end(args); + VA_ARGS_GET(method, g, p); } this->lock->read_lock(this->lock); - enumerator = this->dhs->create_enumerator(this->dhs); + enumerator = this->kes->create_enumerator(this->kes); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->algo == group) + if (entry->algo == method) { - if (this->test_on_create && group != MODP_CUSTOM && - !this->tester->test_dh(this->tester, group, - entry->create_dh, NULL, entry->plugin_name)) + if (this->test_on_create && method != MODP_CUSTOM && + !this->tester->test_ke(this->tester, method, + entry->create_ke, NULL, entry->plugin_name)) { continue; } - diffie_hellman = entry->create_dh(group, g, p); - if (diffie_hellman) + ke = entry->create_ke(method, g, p); + if (ke) { break; } @@ -522,7 +518,7 @@ METHOD(crypto_factory_t, create_dh, diffie_hellman_t*, } enumerator->destroy(enumerator); this->lock->unlock(this->lock); - return diffie_hellman; + return ke; } /** @@ -935,36 +931,36 @@ METHOD(crypto_factory_t, remove_nonce_gen, void, this->lock->unlock(this->lock); } -METHOD(crypto_factory_t, add_dh, bool, - private_crypto_factory_t *this, diffie_hellman_group_t group, - const char *plugin_name, dh_constructor_t create) +METHOD(crypto_factory_t, add_ke, bool, + private_crypto_factory_t *this, key_exchange_method_t group, + const char *plugin_name, ke_constructor_t create) { u_int speed = 0; if (!this->test_on_add || - this->tester->test_dh(this->tester, group, create, + this->tester->test_ke(this->tester, group, create, this->bench ? &speed : NULL, plugin_name)) { - add_entry(this, this->dhs, group, plugin_name, 0, create); + add_entry(this, this->kes, group, plugin_name, 0, create); return TRUE; } this->test_failures++; return FALSE; } -METHOD(crypto_factory_t, remove_dh, void, - private_crypto_factory_t *this, dh_constructor_t create) +METHOD(crypto_factory_t, remove_ke, void, + private_crypto_factory_t *this, ke_constructor_t create) { entry_t *entry; enumerator_t *enumerator; this->lock->write_lock(this->lock); - enumerator = this->dhs->create_enumerator(this->dhs); + enumerator = this->kes->create_enumerator(this->kes); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->create_dh == create) + if (entry->create_ke == create) { - this->dhs->remove_at(this->dhs, enumerator); + this->kes->remove_at(this->kes, enumerator); free(entry); } } @@ -1190,11 +1186,11 @@ METHOD(crypto_factory_t, create_drbg_enumerator, enumerator_t*, return create_enumerator(this, this->drbgs, drbg_filter); } -CALLBACK(dh_filter, bool, +CALLBACK(ke_filter, bool, void *n, enumerator_t *orig, va_list args) { entry_t *entry; - diffie_hellman_group_t *algo; + key_exchange_method_t *algo; const char **plugin_name; VA_ARGS_VGET(args, algo, plugin_name); @@ -1208,10 +1204,10 @@ CALLBACK(dh_filter, bool, return FALSE; } -METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*, +METHOD(crypto_factory_t, create_ke_enumerator, enumerator_t*, private_crypto_factory_t *this) { - return create_enumerator(this, this->dhs, dh_filter); + return create_enumerator(this, this->kes, ke_filter); } CALLBACK(rng_filter, bool, @@ -1283,8 +1279,8 @@ METHOD(crypto_factory_t, add_test_vector, void, return this->tester->add_drbg_vector(this->tester, vector); case RANDOM_NUMBER_GENERATOR: return this->tester->add_rng_vector(this->tester, vector); - case DIFFIE_HELLMAN_GROUP: - return this->tester->add_dh_vector(this->tester, vector); + case KEY_EXCHANGE_METHOD: + return this->tester->add_ke_vector(this->tester, vector); default: DBG1(DBG_LIB, "%N test vectors not supported, ignored", transform_type_names, type); @@ -1354,9 +1350,9 @@ METHOD(enumerator_t, verify_enumerate, bool, *valid = this->tester->test_rng(this->tester, entry->algo, entry->create_rng, NULL, entry->plugin_name); break; - case DIFFIE_HELLMAN_GROUP: - *valid = this->tester->test_dh(this->tester, entry->algo, - entry->create_dh, NULL, entry->plugin_name); + case KEY_EXCHANGE_METHOD: + *valid = this->tester->test_ke(this->tester, entry->algo, + entry->create_ke, NULL, entry->plugin_name); break; default: return FALSE; @@ -1410,8 +1406,8 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*, case RANDOM_NUMBER_GENERATOR: inner = this->rngs->create_enumerator(this->rngs); break; - case DIFFIE_HELLMAN_GROUP: - inner = this->dhs->create_enumerator(this->dhs); + case KEY_EXCHANGE_METHOD: + inner = this->kes->create_enumerator(this->kes); break; default: this->lock->unlock(this->lock); @@ -1444,7 +1440,7 @@ METHOD(crypto_factory_t, destroy, void, this->drbgs->destroy(this->drbgs); this->rngs->destroy(this->rngs); this->nonce_gens->destroy(this->nonce_gens); - this->dhs->destroy(this->dhs); + this->kes->destroy(this->kes); this->tester->destroy(this->tester); this->lock->destroy(this->lock); free(this); @@ -1469,7 +1465,7 @@ crypto_factory_t *crypto_factory_create() .create_drbg = _create_drbg, .create_rng = _create_rng, .create_nonce_gen = _create_nonce_gen, - .create_dh = _create_dh, + .create_ke = _create_ke, .add_crypter = _add_crypter, .remove_crypter = _remove_crypter, .add_aead = _add_aead, @@ -1490,8 +1486,8 @@ crypto_factory_t *crypto_factory_create() .remove_rng = _remove_rng, .add_nonce_gen = _add_nonce_gen, .remove_nonce_gen = _remove_nonce_gen, - .add_dh = _add_dh, - .remove_dh = _remove_dh, + .add_ke = _add_ke, + .remove_ke = _remove_ke, .create_crypter_enumerator = _create_crypter_enumerator, .create_aead_enumerator = _create_aead_enumerator, .create_signer_enumerator = _create_signer_enumerator, @@ -1500,7 +1496,7 @@ crypto_factory_t *crypto_factory_create() .create_xof_enumerator = _create_xof_enumerator, .create_kdf_enumerator = _create_kdf_enumerator, .create_drbg_enumerator = _create_drbg_enumerator, - .create_dh_enumerator = _create_dh_enumerator, + .create_ke_enumerator = _create_ke_enumerator, .create_rng_enumerator = _create_rng_enumerator, .create_nonce_gen_enumerator = _create_nonce_gen_enumerator, .add_test_vector = _add_test_vector, @@ -1517,7 +1513,7 @@ crypto_factory_t *crypto_factory_create() .drbgs = linked_list_create(), .rngs = linked_list_create(), .nonce_gens = linked_list_create(), - .dhs = linked_list_create(), + .kes = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), .tester = crypto_tester_create(), .test_on_add = lib->settings->get_bool(lib->settings, diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h index 25f39a2b8..7961fadc5 100644 --- a/src/libstrongswan/crypto/crypto_factory.h +++ b/src/libstrongswan/crypto/crypto_factory.h @@ -37,7 +37,7 @@ typedef struct crypto_factory_t crypto_factory_t; #include #include #include -#include +#include #include #define CRYPTO_MAX_ALG_LINE 120 /* characters */ @@ -97,12 +97,12 @@ typedef rng_t* (*rng_constructor_t)(rng_quality_t quality); typedef nonce_gen_t* (*nonce_gen_constructor_t)(); /** - * Constructor function for diffie hellman + * Constructor function for key exchange methods * - * The DH constructor accepts additional arguments for: + * The key exchange method constructor accepts additional arguments for: * - MODP_CUSTOM: chunk_t generator, chunk_t prime */ -typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group, ...); +typedef key_exchange_t* (*ke_constructor_t)(key_exchange_method_t method, ...); /** * Handles crypto modules and creates instances. @@ -207,15 +207,15 @@ struct crypto_factory_t { nonce_gen_t* (*create_nonce_gen)(crypto_factory_t *this); /** - * Create a diffie hellman instance. + * Create a key exchange method instance. * - * Additional arguments are passed to the DH constructor. + * Additional arguments are passed to the key exchange method constructor. * - * @param group diffie hellman group - * @return diffie_hellman_t instance, NULL if not supported + * @param method key exchange method + * @return key_exchange_t instance, NULL if not supported */ - diffie_hellman_t* (*create_dh)(crypto_factory_t *this, - diffie_hellman_group_t group, ...); + key_exchange_t* (*create_ke)(crypto_factory_t *this, + key_exchange_method_t method, ...); /** * Register a crypter constructor. @@ -402,22 +402,22 @@ struct crypto_factory_t { nonce_gen_constructor_t create); /** - * Register a diffie hellman constructor. + * Register a key exchange method constructor. * - * @param group dh group to constructor + * @param method key exchange method to constructor * @param plugin_name plugin that registered this algorithm * @param create constructor function for that algorithm * @return TRUE if registered, FALSE if test vector failed */ - bool (*add_dh)(crypto_factory_t *this, diffie_hellman_group_t group, - const char *plugin_name, dh_constructor_t create); + bool (*add_ke)(crypto_factory_t *this, key_exchange_method_t method, + const char *plugin_name, ke_constructor_t create); /** - * Unregister a diffie hellman constructor. + * Unregister a key exchange method constructor. * * @param create constructor function to unregister */ - void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create); + void (*remove_ke)(crypto_factory_t *this, ke_constructor_t create); /** * Create an enumerator over all registered crypter algorithms. @@ -476,11 +476,11 @@ struct crypto_factory_t { enumerator_t* (*create_drbg_enumerator)(crypto_factory_t *this); /** - * Create an enumerator over all registered diffie hellman groups. + * Create an enumerator over all registered key exchange method. * - * @return enumerator over diffie_hellman_group_t, plugin + * @return enumerator over key_exchange_method_t, plugin */ - enumerator_t* (*create_dh_enumerator)(crypto_factory_t *this); + enumerator_t* (*create_ke_enumerator)(crypto_factory_t *this); /** * Create an enumerator over all registered random generators. diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index d10c79067..b87c4c73a 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -85,9 +85,9 @@ struct private_crypto_tester_t { linked_list_t *rng; /** - * List of Diffie-Hellman test vectors + * List of key exchange method test vectors */ - linked_list_t *dh; + linked_list_t *ke; /** * Is a test vector required to pass a test? @@ -1649,13 +1649,13 @@ failure: } /** - * Benchmark a DH backend + * Benchmark a key exchange backend */ -static u_int bench_dh(private_crypto_tester_t *this, - diffie_hellman_group_t group, dh_constructor_t create) +static u_int bench_ke(private_crypto_tester_t *this, + key_exchange_method_t method, ke_constructor_t create) { chunk_t pub = chunk_empty, shared = chunk_empty; - diffie_hellman_t *dh; + key_exchange_t *ke; struct timespec start; u_int runs; @@ -1663,46 +1663,46 @@ static u_int bench_dh(private_crypto_tester_t *this, start_timing(&start); while (end_timing(&start) < this->bench_time) { - dh = create(group); - if (!dh) + ke = create(method); + if (!ke) { return 0; } - if (dh->get_my_public_value(dh, &pub) && - dh->set_other_public_value(dh, pub) && - dh->get_shared_secret(dh, &shared)) + if (ke->get_public_key(ke, &pub) && + ke->set_public_key(ke, pub) && + ke->get_shared_secret(ke, &shared)) { runs++; } chunk_free(&pub); chunk_free(&shared); - dh->destroy(dh); + ke->destroy(ke); } return runs; } -METHOD(crypto_tester_t, test_dh, bool, - private_crypto_tester_t *this, diffie_hellman_group_t group, - dh_constructor_t create, u_int *speed, const char *plugin_name) +METHOD(crypto_tester_t, test_ke, bool, + private_crypto_tester_t *this, key_exchange_method_t method, + ke_constructor_t create, u_int *speed, const char *plugin_name) { enumerator_t *enumerator; - dh_test_vector_t *v; + ke_test_vector_t *v; bool failed = FALSE; u_int tested = 0; - enumerator = this->dh->create_enumerator(this->dh); + enumerator = this->ke->create_enumerator(this->ke); while (enumerator->enumerate(enumerator, &v)) { - diffie_hellman_t *a, *b; + key_exchange_t *a, *b; chunk_t apub, bpub, asec, bsec; - if (v->group != group) + if (v->method != method) { continue; } - a = create(group); - b = create(group); + a = create(method); + b = create(method); if (!a || !b) { DESTROY_IF(a); @@ -1710,11 +1710,11 @@ METHOD(crypto_tester_t, test_dh, bool, failed = TRUE; tested++; DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed", - diffie_hellman_group_names, group, plugin_name); + key_exchange_method_names, method, plugin_name); break; } - if (!a->set_private_value || !b->set_private_value) + if (!a->set_private_key || !b->set_private_key) { /* does not support testing */ a->destroy(a); b->destroy(b); @@ -1725,23 +1725,23 @@ METHOD(crypto_tester_t, test_dh, bool, apub = bpub = asec = bsec = chunk_empty; - if (!a->set_private_value(a, chunk_create(v->priv_a, v->priv_len)) || - !b->set_private_value(b, chunk_create(v->priv_b, v->priv_len))) + if (!a->set_private_key(a, chunk_create(v->priv_a, v->priv_len)) || + !b->set_private_key(b, chunk_create(v->priv_b, v->priv_len))) { goto failure; } - if (!a->get_my_public_value(a, &apub) || + if (!a->get_public_key(a, &apub) || !chunk_equals(apub, chunk_create(v->pub_a, v->pub_len))) { goto failure; } - if (!b->get_my_public_value(b, &bpub) || + if (!b->get_public_key(b, &bpub) || !chunk_equals(bpub, chunk_create(v->pub_b, v->pub_len))) { goto failure; } - if (!a->set_other_public_value(a, bpub) || - !b->set_other_public_value(b, apub)) + if (!a->set_public_key(a, bpub) || + !b->set_public_key(b, apub)) { goto failure; } @@ -1767,7 +1767,7 @@ failure: if (failed) { DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", - diffie_hellman_group_names, group, plugin_name, get_name(v)); + key_exchange_method_names, method, plugin_name, get_name(v)); break; } } @@ -1776,21 +1776,21 @@ failure: { DBG1(DBG_LIB, "%s %N[%s]: no test vectors found / untestable", this->required ? "disabled" : "enabled ", - diffie_hellman_group_names, group, plugin_name); + key_exchange_method_names, method, plugin_name); return !this->required; } if (!failed) { if (speed) { - *speed = bench_dh(this, group, create); + *speed = bench_ke(this, method, create); DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points", - diffie_hellman_group_names, group, plugin_name, tested, *speed); + key_exchange_method_names, method, plugin_name, tested, *speed); } else { DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors", - diffie_hellman_group_names, group, plugin_name, tested); + key_exchange_method_names, method, plugin_name, tested); } } return !failed; @@ -1850,10 +1850,10 @@ METHOD(crypto_tester_t, add_rng_vector, void, this->rng->insert_last(this->rng, vector); } -METHOD(crypto_tester_t, add_dh_vector, void, - private_crypto_tester_t *this, dh_test_vector_t *vector) +METHOD(crypto_tester_t, add_ke_vector, void, + private_crypto_tester_t *this, ke_test_vector_t *vector) { - this->dh->insert_last(this->dh, vector); + this->ke->insert_last(this->ke, vector); } METHOD(crypto_tester_t, destroy, void, @@ -1868,7 +1868,7 @@ METHOD(crypto_tester_t, destroy, void, this->kdf->destroy(this->kdf); this->drbg->destroy(this->drbg); this->rng->destroy(this->rng); - this->dh->destroy(this->dh); + this->ke->destroy(this->ke); free(this); } @@ -1890,7 +1890,7 @@ crypto_tester_t *crypto_tester_create() .test_kdf = _test_kdf, .test_drbg = _test_drbg, .test_rng = _test_rng, - .test_dh = _test_dh, + .test_ke = _test_ke, .add_crypter_vector = _add_crypter_vector, .add_aead_vector = _add_aead_vector, .add_signer_vector = _add_signer_vector, @@ -1900,7 +1900,7 @@ crypto_tester_t *crypto_tester_create() .add_kdf_vector = _add_kdf_vector, .add_drbg_vector = _add_drbg_vector, .add_rng_vector = _add_rng_vector, - .add_dh_vector = _add_dh_vector, + .add_ke_vector = _add_ke_vector, .destroy = _destroy, }, .crypter = linked_list_create(), @@ -1912,7 +1912,7 @@ crypto_tester_t *crypto_tester_create() .kdf = linked_list_create(), .drbg = linked_list_create(), .rng = linked_list_create(), - .dh = linked_list_create(), + .ke = linked_list_create(), .required = lib->settings->get_bool(lib->settings, "%s.crypto_test.required", FALSE, lib->ns), diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h index c5aa7ea4f..95a9342f0 100644 --- a/src/libstrongswan/crypto/crypto_tester.h +++ b/src/libstrongswan/crypto/crypto_tester.h @@ -37,7 +37,7 @@ typedef struct kdf_test_vector_t kdf_test_vector_t; typedef struct kdf_test_args_t kdf_test_args_t; typedef struct drbg_test_vector_t drbg_test_vector_t; typedef struct rng_test_vector_t rng_test_vector_t; -typedef struct dh_test_vector_t dh_test_vector_t; +typedef struct ke_test_vector_t ke_test_vector_t; struct crypter_test_vector_t { /** encryption algorithm this vector tests */ @@ -182,20 +182,20 @@ struct rng_test_vector_t { void *user; }; -struct dh_test_vector_t { - /** diffie hellman group to test */ - diffie_hellman_group_t group; - /** private value of alice */ +struct ke_test_vector_t { + /** key exchange method to test */ + key_exchange_method_t method; + /** private key of alice */ u_char *priv_a; - /** private value of bob */ + /** private key of bob */ u_char *priv_b; - /** length of private values */ + /** length of private keys */ size_t priv_len; - /** expected public value of alice */ + /** expected public key of alice */ u_char *pub_a; - /** expected public value of bob */ + /** expected public key of bob */ u_char *pub_b; - /** size of public values */ + /** size of public keys */ size_t pub_len; /** expected shared secret */ u_char *shared; @@ -318,15 +318,15 @@ struct crypto_tester_t { rng_constructor_t create, u_int *speed, const char *plugin_name); /** - * Test a Diffie-Hellman implementation. + * Test a key exchange implementation. * - * @param group group to test - * @param create constructor function for the DH backend - * @param speed speed test result, NULL to omit + * @param ke key exchange method to test + * @param create constructor function for the key exchange method + * @param speed speeed test result, NULL to omit * @return TRUE if test passed */ - bool (*test_dh)(crypto_tester_t *this, diffie_hellman_group_t group, - dh_constructor_t create, + bool (*test_ke)(crypto_tester_t *this, key_exchange_method_t ke, + ke_constructor_t create, u_int *speed, const char *plugin_name); /** @@ -397,7 +397,7 @@ struct crypto_tester_t { * * @param vector pointer to test vector */ - void (*add_dh_vector)(crypto_tester_t *this, dh_test_vector_t *vector); + void (*add_ke_vector)(crypto_tester_t *this, ke_test_vector_t *vector); /** * Destroy a crypto_tester_t. diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/key_exchange.c similarity index 93% rename from src/libstrongswan/crypto/diffie_hellman.c rename to src/libstrongswan/crypto/key_exchange.c index d7e4a88fb..d672ec7e8 100644 --- a/src/libstrongswan/crypto/diffie_hellman.c +++ b/src/libstrongswan/crypto/key_exchange.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Tobias Brunner + * Copyright (C) 2010-2019 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter * @@ -16,15 +16,15 @@ * for more details. */ -#include "diffie_hellman.h" +#include "key_exchange.h" -ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT, - "MODP_NONE", +ENUM_BEGIN(key_exchange_method_names, KE_NONE, MODP_1024_BIT, + "KE_NONE", "MODP_768", "MODP_1024"); -ENUM_NEXT(diffie_hellman_group_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT, +ENUM_NEXT(key_exchange_method_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT, "MODP_1536"); -ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT, +ENUM_NEXT(key_exchange_method_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT, "MODP_2048", "MODP_3072", "MODP_4096", @@ -33,7 +33,7 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT, "ECP_256", "ECP_384", "ECP_521"); -ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, CURVE_448, ECP_521_BIT, +ENUM_NEXT(key_exchange_method_names, MODP_1024_160, CURVE_448, ECP_521_BIT, "MODP_1024_160", "MODP_2048_224", "MODP_2048_256", @@ -45,26 +45,26 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, CURVE_448, ECP_521_BIT, "ECP_512_BP", "CURVE_25519", "CURVE_448"); -ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_NULL, CURVE_448, +ENUM_NEXT(key_exchange_method_names, MODP_NULL, MODP_NULL, CURVE_448, "MODP_NULL"); -ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL, +ENUM_NEXT(key_exchange_method_names, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL, "NTRU_112", "NTRU_128", "NTRU_192", "NTRU_256"); -ENUM_NEXT(diffie_hellman_group_names, NH_128_BIT, NH_128_BIT, NTRU_256_BIT, +ENUM_NEXT(key_exchange_method_names, NH_128_BIT, NH_128_BIT, NTRU_256_BIT, "NEWHOPE_128"); -ENUM_NEXT(diffie_hellman_group_names, MODP_CUSTOM, MODP_CUSTOM, NH_128_BIT, +ENUM_NEXT(key_exchange_method_names, MODP_CUSTOM, MODP_CUSTOM, NH_128_BIT, "MODP_CUSTOM"); -ENUM_END(diffie_hellman_group_names, MODP_CUSTOM); +ENUM_END(key_exchange_method_names, MODP_CUSTOM); -ENUM_BEGIN(diffie_hellman_group_names_short, MODP_NONE, MODP_1024_BIT, - "modpnone", +ENUM_BEGIN(key_exchange_method_names_short, KE_NONE, MODP_1024_BIT, + "none", "modp768", "modp1024"); -ENUM_NEXT(diffie_hellman_group_names_short, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT, +ENUM_NEXT(key_exchange_method_names_short, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT, "modp1536"); -ENUM_NEXT(diffie_hellman_group_names_short, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT, +ENUM_NEXT(key_exchange_method_names_short, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT, "modp2048", "modp3072", "modp4096", @@ -73,7 +73,7 @@ ENUM_NEXT(diffie_hellman_group_names_short, MODP_2048_BIT, ECP_521_BIT, MODP_153 "ecp256", "ecp384", "ecp521"); -ENUM_NEXT(diffie_hellman_group_names_short, MODP_1024_160, CURVE_448, ECP_521_BIT, +ENUM_NEXT(key_exchange_method_names_short, MODP_1024_160, CURVE_448, ECP_521_BIT, "modp1024s160", "modp2048s224", "modp2048s256", @@ -85,27 +85,27 @@ ENUM_NEXT(diffie_hellman_group_names_short, MODP_1024_160, CURVE_448, ECP_521_BI "ecp512bp", "curve25519", "curve448"); -ENUM_NEXT(diffie_hellman_group_names_short, MODP_NULL, MODP_NULL, CURVE_448, +ENUM_NEXT(key_exchange_method_names_short, MODP_NULL, MODP_NULL, CURVE_448, "modpnull"); -ENUM_NEXT(diffie_hellman_group_names_short, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL, +ENUM_NEXT(key_exchange_method_names_short, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL, "ntru112", "ntru128", "ntru192", "ntru256"); -ENUM_NEXT(diffie_hellman_group_names_short, NH_128_BIT, NH_128_BIT, NTRU_256_BIT, +ENUM_NEXT(key_exchange_method_names_short, NH_128_BIT, NH_128_BIT, NTRU_256_BIT, "newhope128"); -ENUM_NEXT(diffie_hellman_group_names_short, MODP_CUSTOM, MODP_CUSTOM, NH_128_BIT, +ENUM_NEXT(key_exchange_method_names_short, MODP_CUSTOM, MODP_CUSTOM, NH_128_BIT, "modpcustom"); -ENUM_END(diffie_hellman_group_names_short, MODP_CUSTOM); +ENUM_END(key_exchange_method_names_short, MODP_CUSTOM); /** - * List of known diffie hellman group parameters. + * List of known Diffie-Hellman group parameters. */ static struct { /* Public part of the struct */ diffie_hellman_params_t public; /* The group identifier as specified in IKEv2 */ - diffie_hellman_group_t group; + key_exchange_method_t group; } dh_params[] = { { .group = MODP_768_BIT, .public = { @@ -475,8 +475,8 @@ static struct { }, }; -/** - * See header. +/* + * Described in header */ void diffie_hellman_init() { @@ -500,16 +500,16 @@ void diffie_hellman_init() } } -/** - * Described in header. +/* + * Described in header */ -diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group) +diffie_hellman_params_t *diffie_hellman_get_params(key_exchange_method_t ke) { int i; for (i = 0; i < countof(dh_params); i++) { - if (dh_params[i].group == group) + if (dh_params[i].group == ke) { return &dh_params[i].public; } @@ -517,12 +517,12 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group) return NULL; } -/** - * See header. +/* + * Described in header */ -bool diffie_hellman_group_is_ec(diffie_hellman_group_t group) +bool key_exchange_is_ecdh(key_exchange_method_t ke) { - switch (group) + switch (ke) { case ECP_256_BIT: case ECP_384_BIT: @@ -541,15 +541,15 @@ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group) } } -/** - * See header. +/* + * Described in header */ -bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value) +bool key_exchange_verify_pubkey(key_exchange_method_t ke, chunk_t value) { diffie_hellman_params_t *params; bool valid = FALSE; - switch (group) + switch (ke) { case MODP_768_BIT: case MODP_1024_BIT: @@ -562,7 +562,7 @@ bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value) case MODP_1024_160: case MODP_2048_224: case MODP_2048_256: - params = diffie_hellman_get_params(group); + params = diffie_hellman_get_params(ke); if (params) { valid = value.len == params->prime.len; @@ -607,15 +607,15 @@ bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value) case MODP_CUSTOM: valid = TRUE; break; - case MODP_NONE: + case KE_NONE: /* fail */ break; - /* compile-warn unhandled groups, fail verification */ + /* compile-warn unhandled methods, fail verification */ } if (!valid) { DBG1(DBG_ENC, "invalid DH public value size (%zu bytes) for %N", - value.len, diffie_hellman_group_names, group); + value.len, key_exchange_method_names, ke); } return valid; } diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/key_exchange.h similarity index 54% rename from src/libstrongswan/crypto/diffie_hellman.h rename to src/libstrongswan/crypto/key_exchange.h index f1127602e..70d6d4993 100644 --- a/src/libstrongswan/crypto/diffie_hellman.h +++ b/src/libstrongswan/crypto/key_exchange.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Tobias Brunner + * Copyright (C) 2010-2019 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * @@ -17,21 +17,21 @@ */ /** - * @defgroup diffie_hellman diffie_hellman + * @defgroup key_exchange key_exchange * @{ @ingroup crypto */ -#ifndef DIFFIE_HELLMAN_H_ -#define DIFFIE_HELLMAN_H_ +#ifndef KEY_EXCHANGE_H_ +#define KEY_EXCHANGE_H_ -typedef enum diffie_hellman_group_t diffie_hellman_group_t; -typedef struct diffie_hellman_t diffie_hellman_t; +typedef enum key_exchange_method_t key_exchange_method_t; +typedef struct key_exchange_t key_exchange_t; typedef struct diffie_hellman_params_t diffie_hellman_params_t; #include /** - * Diffie-Hellman group. + * Key exchange method. * * The modulus (or group) to use for a Diffie-Hellman calculation. * See IKEv2 RFC 3.3.2 and RFC 3526. @@ -40,8 +40,8 @@ typedef struct diffie_hellman_params_t diffie_hellman_params_t; * ECC Brainpool groups are defined in RFC 6954. * Curve25519 and Curve448 groups are defined in RFC 8031. */ -enum diffie_hellman_group_t { - MODP_NONE = 0, +enum key_exchange_method_t { + KE_NONE = 0, MODP_768_BIT = 1, MODP_1024_BIT = 2, MODP_1536_BIT = 5, @@ -79,80 +79,79 @@ enum diffie_hellman_group_t { }; /** - * enum name for diffie_hellman_group_t. + * enum name for key_exchange_method_t. */ -extern enum_name_t *diffie_hellman_group_names; +extern enum_name_t *key_exchange_method_names; /** - * enum names for diffie_hellman_group_t (matching proposal keywords). + * enum names for key_exchange_method_t (matching proposal keywords). */ -extern enum_name_t *diffie_hellman_group_names_short; +extern enum_name_t *key_exchange_method_names_short; /** - * Implementation of the Diffie-Hellman algorithm, as in RFC2631. + * Implementation of a key exchange algorithms (e.g. Diffie-Hellman). */ -struct diffie_hellman_t { +struct key_exchange_t { /** - * Returns the shared secret of this diffie hellman exchange. + * Returns the shared secret of this key exchange method. * - * Space for returned secret is allocated and must be freed by the caller. - * - * @param secret shared secret will be written into this chunk + * @param secret shared secret (allocated) * @return TRUE if shared secret computed successfully */ - bool (*get_shared_secret)(diffie_hellman_t *this, chunk_t *secret) + bool (*get_shared_secret)(key_exchange_t *this, chunk_t *secret) __attribute__((warn_unused_result)); /** - * Sets the public value of partner. + * Sets the public key from the peer. * - * Chunk gets cloned and can be destroyed afterwards. + * @note This operation should be relatively quick. Costly public key + * validation operations or key derivation should be implemented in + * get_shared_secret(). * - * @param value public value of partner - * @return TRUE if other public value verified and set + * @param value public key of peer + * @return TRUE if other public key verified and set */ - bool (*set_other_public_value)(diffie_hellman_t *this, chunk_t value) + bool (*set_public_key)(key_exchange_t *this, chunk_t value) __attribute__((warn_unused_result)); /** - * Gets the own public value to transmit. + * Gets the own public key to transmit. * - * Space for returned chunk is allocated and must be freed by the caller. - * - * @param value public value of caller is stored at this location - * @return TRUE if public value retrieved + * @param value public key (allocated) + * @return TRUE if public key retrieved */ - bool (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value) + bool (*get_public_key)(key_exchange_t *this, chunk_t *value) __attribute__((warn_unused_result)); /** - * Set an explicit own private value to use. + * Set an explicit own private key to use. * * Calling this method is usually not required, as the DH backend generates * an appropriate private value itself. It is optional to implement, and - * used mostly for testing purposes. + * used mostly for testing purposes. The private key may be the actual key + * or a seed for a DRBG. * - * @param value private value to set + * @param value private key value to set */ - bool (*set_private_value)(diffie_hellman_t *this, chunk_t value) + bool (*set_private_key)(key_exchange_t *this, chunk_t value) __attribute__((warn_unused_result)); /** - * Get the DH group used. + * Get the key exchange method used. * - * @return DH group set in construction + * @return key exchange method set in construction */ - diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this); + key_exchange_method_t (*get_method)(key_exchange_t *this); /** - * Destroys a diffie_hellman_t object. + * Destroys a key_exchange_t object. */ - void (*destroy) (diffie_hellman_t *this); + void (*destroy)(key_exchange_t *this); }; /** - * Parameters for a specific diffie hellman group. + * Parameters for a specific Diffie-Hellman group. */ struct diffie_hellman_params_t { @@ -183,31 +182,31 @@ struct diffie_hellman_params_t { void diffie_hellman_init(); /** - * Get the parameters associated with the specified diffie hellman group. + * Get the parameters associated with the specified Diffie-Hellman group. * * Before calling this method, use diffie_hellman_init() to initialize the * DH group table. This is usually done by library_init(). * - * @param group DH group + * @param ke key exchange method (DH group) * @return The parameters or NULL, if the group is not supported */ -diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group); +diffie_hellman_params_t *diffie_hellman_get_params(key_exchange_method_t ke); /** - * Check if a given DH group is an ECDH group + * Check if a given key exchange method is an ECDH group. * - * @param group group to check - * @return TRUE if group is an ECP group + * @param ke key exchange method to check + * @return TRUE if key exchange method is an ECP group */ -bool diffie_hellman_group_is_ec(diffie_hellman_group_t group); +bool key_exchange_is_ecdh(key_exchange_method_t ke); /** - * Check if a diffie hellman public value is valid for given group. + * Check if a public key is valid for given key exchange method. * - * @param group group the value is used in - * @param value public DH value to check - * @return TRUE if value looks valid for group + * @param ke key exchange method + * @param value public key to check + * @return TRUE if value looks valid */ -bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value); +bool key_exchange_verify_pubkey(key_exchange_method_t ke, chunk_t value); -#endif /** DIFFIE_HELLMAN_H_ @}*/ +#endif /** KEY_EXCHANGE_H_ @}*/ diff --git a/src/libstrongswan/crypto/proposal/proposal.c b/src/libstrongswan/crypto/proposal/proposal.c index 78daea39b..1ad04db4e 100644 --- a/src/libstrongswan/crypto/proposal/proposal.c +++ b/src/libstrongswan/crypto/proposal/proposal.c @@ -252,34 +252,37 @@ METHOD(proposal_t, get_algorithm, bool, return found; } -METHOD(proposal_t, has_dh_group, bool, - private_proposal_t *this, diffie_hellman_group_t group) +METHOD(proposal_t, has_transform, bool, + private_proposal_t *this, transform_type_t type, uint16_t alg) { bool found = FALSE, any = FALSE; enumerator_t *enumerator; uint16_t current; - enumerator = create_enumerator(this, DIFFIE_HELLMAN_GROUP); + enumerator = create_enumerator(this, type); while (enumerator->enumerate(enumerator, ¤t, NULL)) { - any = TRUE; - if (current == group) + if (current) { - found = TRUE; - break; + any = TRUE; + if (alg && current == alg) + { + found = TRUE; + break; + } } } enumerator->destroy(enumerator); - if (!any && group == MODP_NONE) + if (!any && !alg) { found = TRUE; } return found; } -METHOD(proposal_t, promote_dh_group, bool, - private_proposal_t *this, diffie_hellman_group_t group) +METHOD(proposal_t, promote_transform, bool, + private_proposal_t *this, transform_type_t type, uint16_t alg) { enumerator_t *enumerator; entry_t *entry; @@ -288,8 +291,8 @@ METHOD(proposal_t, promote_dh_group, bool, enumerator = array_create_enumerator(this->transforms); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->type == DIFFIE_HELLMAN_GROUP && - entry->alg == group) + if (entry->type == type && + entry->alg == alg) { array_remove_at(this->transforms, enumerator); found = TRUE; @@ -300,8 +303,8 @@ METHOD(proposal_t, promote_dh_group, bool, if (found) { entry_t entry = { - .type = DIFFIE_HELLMAN_GROUP, - .alg = group, + .type = type, + .alg = alg, }; array_insert(this->transforms, ARRAY_HEAD, &entry); } @@ -319,7 +322,7 @@ static bool select_algo(private_proposal_t *this, proposal_t *other, uint16_t alg1, alg2, ks1, ks2; bool found = FALSE, optional = FALSE; - if (type == DIFFIE_HELLMAN_GROUP) + if (type == KEY_EXCHANGE_METHOD) { optional = this->protocol == PROTO_ESP || this->protocol == PROTO_AH; } @@ -408,7 +411,7 @@ static bool select_algos(private_proposal_t *this, proposal_t *other, { continue; } - if (type == DIFFIE_HELLMAN_GROUP && (flags & PROPOSAL_SKIP_DH)) + if (type == KEY_EXCHANGE_METHOD && (flags & PROPOSAL_SKIP_KE)) { continue; } @@ -601,7 +604,7 @@ METHOD(proposal_t, clone_, proposal_t*, { continue; } - if (entry->type == DIFFIE_HELLMAN_GROUP && (flags & PROPOSAL_SKIP_DH)) + if (entry->type == KEY_EXCHANGE_METHOD && (flags & PROPOSAL_SKIP_KE)) { continue; } @@ -692,17 +695,17 @@ static bool check_proposal(private_proposal_t *this) DBG1(DBG_CFG, "a PRF algorithm is mandatory in IKE proposals"); return FALSE; } - /* remove MODP_NONE from IKE proposal */ + /* remove KE_NONE from IKE proposal */ e = array_create_enumerator(this->transforms); while (e->enumerate(e, &entry)) { - if (entry->type == DIFFIE_HELLMAN_GROUP && !entry->alg) + if (entry->type == KEY_EXCHANGE_METHOD && !entry->alg) { array_remove_at(this->transforms, e); } } e->destroy(e); - if (!get_algorithm(this, DIFFIE_HELLMAN_GROUP, NULL, NULL)) + if (!get_algorithm(this, KEY_EXCHANGE_METHOD, NULL, NULL)) { DBG1(DBG_CFG, "a DH group is mandatory in IKE proposals"); return FALSE; @@ -943,8 +946,8 @@ proposal_t *proposal_create_v1(protocol_id_t protocol, uint8_t number, .add_algorithm = _add_algorithm, .create_enumerator = _create_enumerator, .get_algorithm = _get_algorithm, - .has_dh_group = _has_dh_group, - .promote_dh_group = _promote_dh_group, + .has_transform = _has_transform, + .promote_transform = _promote_transform, .select = _select_proposal, .matches = _matches, .get_protocol = _get_protocol, @@ -983,7 +986,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) encryption_algorithm_t encryption; integrity_algorithm_t integrity; pseudo_random_function_t prf; - diffie_hellman_group_t group; + key_exchange_method_t group; const char *plugin_name; if (aead) @@ -1175,7 +1178,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) enumerator->destroy(enumerator); /* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */ - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + enumerator = lib->crypto->create_ke_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) { switch (group) @@ -1192,7 +1195,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) case NTRU_192_BIT: case NTRU_256_BIT: case NH_128_BIT: - add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); + add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0); break; default: break; @@ -1201,7 +1204,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) enumerator->destroy(enumerator); /* Round 2 adds other algorithms with at least 128 bit security strength */ - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + enumerator = lib->crypto->create_ke_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) { switch (group) @@ -1210,7 +1213,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) case MODP_4096_BIT: case MODP_6144_BIT: case MODP_8192_BIT: - add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); + add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0); break; default: break; @@ -1219,7 +1222,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) enumerator->destroy(enumerator); /* Round 3 adds algorithms with less than 128 bit security strength */ - enumerator = lib->crypto->create_dh_enumerator(lib->crypto); + enumerator = lib->crypto->create_ke_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) { switch (group) @@ -1244,7 +1247,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead) /* rarely used */ break; case MODP_2048_BIT: - add_algorithm(this, DIFFIE_HELLMAN_GROUP, group, 0); + add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0); break; default: break; diff --git a/src/libstrongswan/crypto/proposal/proposal.h b/src/libstrongswan/crypto/proposal/proposal.h index 38c2517c0..29fda8b8b 100644 --- a/src/libstrongswan/crypto/proposal/proposal.h +++ b/src/libstrongswan/crypto/proposal/proposal.h @@ -35,7 +35,7 @@ typedef struct proposal_t proposal_t; #include #include #include -#include +#include /** * Protocol ID of a proposal. @@ -61,8 +61,8 @@ enum proposal_selection_flag_t { PROPOSAL_PREFER_SUPPLIED = (1<<0), /** Whether to skip and ignore algorithms from a private range. */ PROPOSAL_SKIP_PRIVATE = (1<<1), - /** Whether to skip and ignore diffie hellman groups. */ - PROPOSAL_SKIP_DH = (1<<2), + /** Whether to skip and ignore key exchange methods. */ + PROPOSAL_SKIP_KE = (1<<2), }; /** @@ -110,21 +110,26 @@ struct proposal_t { uint16_t *alg, uint16_t *key_size); /** - * Check if the proposal has a specific DH group. + * Check if the proposal has a specific transform. * - * @param group group to check for + * @param type kind of algorithm + * @param alg algorithm to check for (if 0, TRUE is returned if + * no transform of the given type is found) * @return TRUE if algorithm included */ - bool (*has_dh_group)(proposal_t *this, diffie_hellman_group_t group); + bool (*has_transform)(proposal_t *this, transform_type_t type, + uint16_t alg); /** - * Move the given DH group to the front of the list if it was contained in + * Move the given transform to the front of the list if it was contained in * the proposal. * - * @param group group to promote + * @param type kind of algorithm + * @param alg algorithm to promote * @return TRUE if algorithm included */ - bool (*promote_dh_group)(proposal_t *this, diffie_hellman_group_t group); + bool (*promote_transform)(proposal_t *this, transform_type_t type, + uint16_t alg); /** * Compare two proposals and select a matching subset. diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt index 4fc37d36d..8456fe4ea 100644 --- a/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt +++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt @@ -20,7 +20,7 @@ #include #include #include -#include +#include %} struct proposal_token { @@ -149,36 +149,37 @@ prfmd5, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0 prfaesxcbc, PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0 prfcamelliaxcbc, PSEUDO_RANDOM_FUNCTION, PRF_CAMELLIA128_XCBC, 0 prfaescmac, PSEUDO_RANDOM_FUNCTION, PRF_AES128_CMAC, 0 -modpnone, DIFFIE_HELLMAN_GROUP, MODP_NONE, 0 -modpnull, DIFFIE_HELLMAN_GROUP, MODP_NULL, 0 -modp768, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0 -modp1024, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0 -modp1536, DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0 -modp2048, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0 -modp3072, DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0 -modp4096, DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0 -modp6144, DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0 -modp8192, DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0 -ecp192, DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0 -ecp224, DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0 -ecp256, DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0 -ecp384, DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0 -ecp521, DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0 -modp1024s160, DIFFIE_HELLMAN_GROUP, MODP_1024_160, 0 -modp2048s224, DIFFIE_HELLMAN_GROUP, MODP_2048_224, 0 -modp2048s256, DIFFIE_HELLMAN_GROUP, MODP_2048_256, 0 -ecp224bp, DIFFIE_HELLMAN_GROUP, ECP_224_BP, 0 -ecp256bp, DIFFIE_HELLMAN_GROUP, ECP_256_BP, 0 -ecp384bp, DIFFIE_HELLMAN_GROUP, ECP_384_BP, 0 -ecp512bp, DIFFIE_HELLMAN_GROUP, ECP_512_BP, 0 -curve25519, DIFFIE_HELLMAN_GROUP, CURVE_25519, 0 -x25519, DIFFIE_HELLMAN_GROUP, CURVE_25519, 0 -curve448, DIFFIE_HELLMAN_GROUP, CURVE_448, 0 -x448, DIFFIE_HELLMAN_GROUP, CURVE_448, 0 -ntru112, DIFFIE_HELLMAN_GROUP, NTRU_112_BIT, 0 -ntru128, DIFFIE_HELLMAN_GROUP, NTRU_128_BIT, 0 -ntru192, DIFFIE_HELLMAN_GROUP, NTRU_192_BIT, 0 -ntru256, DIFFIE_HELLMAN_GROUP, NTRU_256_BIT, 0 -newhope128, DIFFIE_HELLMAN_GROUP, NH_128_BIT, 0 +none, KEY_EXCHANGE_METHOD, KE_NONE, 0 +modpnone, KEY_EXCHANGE_METHOD, KE_NONE, 0 +modpnull, KEY_EXCHANGE_METHOD, MODP_NULL, 0 +modp768, KEY_EXCHANGE_METHOD, MODP_768_BIT, 0 +modp1024, KEY_EXCHANGE_METHOD, MODP_1024_BIT, 0 +modp1536, KEY_EXCHANGE_METHOD, MODP_1536_BIT, 0 +modp2048, KEY_EXCHANGE_METHOD, MODP_2048_BIT, 0 +modp3072, KEY_EXCHANGE_METHOD, MODP_3072_BIT, 0 +modp4096, KEY_EXCHANGE_METHOD, MODP_4096_BIT, 0 +modp6144, KEY_EXCHANGE_METHOD, MODP_6144_BIT, 0 +modp8192, KEY_EXCHANGE_METHOD, MODP_8192_BIT, 0 +ecp192, KEY_EXCHANGE_METHOD, ECP_192_BIT, 0 +ecp224, KEY_EXCHANGE_METHOD, ECP_224_BIT, 0 +ecp256, KEY_EXCHANGE_METHOD, ECP_256_BIT, 0 +ecp384, KEY_EXCHANGE_METHOD, ECP_384_BIT, 0 +ecp521, KEY_EXCHANGE_METHOD, ECP_521_BIT, 0 +modp1024s160, KEY_EXCHANGE_METHOD, MODP_1024_160, 0 +modp2048s224, KEY_EXCHANGE_METHOD, MODP_2048_224, 0 +modp2048s256, KEY_EXCHANGE_METHOD, MODP_2048_256, 0 +ecp224bp, KEY_EXCHANGE_METHOD, ECP_224_BP, 0 +ecp256bp, KEY_EXCHANGE_METHOD, ECP_256_BP, 0 +ecp384bp, KEY_EXCHANGE_METHOD, ECP_384_BP, 0 +ecp512bp, KEY_EXCHANGE_METHOD, ECP_512_BP, 0 +curve25519, KEY_EXCHANGE_METHOD, CURVE_25519, 0 +x25519, KEY_EXCHANGE_METHOD, CURVE_25519, 0 +curve448, KEY_EXCHANGE_METHOD, CURVE_448, 0 +x448, KEY_EXCHANGE_METHOD, CURVE_448, 0 +ntru112, KEY_EXCHANGE_METHOD, NTRU_112_BIT, 0 +ntru128, KEY_EXCHANGE_METHOD, NTRU_128_BIT, 0 +ntru192, KEY_EXCHANGE_METHOD, NTRU_192_BIT, 0 +ntru256, KEY_EXCHANGE_METHOD, NTRU_256_BIT, 0 +newhope128, KEY_EXCHANGE_METHOD, NH_128_BIT, 0 noesn, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0 esn, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0 diff --git a/src/libstrongswan/crypto/transform.c b/src/libstrongswan/crypto/transform.c index ccad0f09a..d7bc21540 100644 --- a/src/libstrongswan/crypto/transform.c +++ b/src/libstrongswan/crypto/transform.c @@ -23,7 +23,7 @@ ENUM_BEGIN(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS "ENCRYPTION_ALGORITHM", "PSEUDO_RANDOM_FUNCTION", "INTEGRITY_ALGORITHM", - "DIFFIE_HELLMAN_GROUP", + "KEY_EXCHANGE_METHOD", "EXTENDED_SEQUENCE_NUMBERS"); ENUM_NEXT(transform_type_names, HASH_ALGORITHM, KEY_DERIVATION_FUNCTION, EXTENDED_SEQUENCE_NUMBERS, @@ -59,8 +59,8 @@ enum_name_t* transform_get_enum_names(transform_type_t type) return pseudo_random_function_names; case INTEGRITY_ALGORITHM: return integrity_algorithm_names; - case DIFFIE_HELLMAN_GROUP: - return diffie_hellman_group_names; + case KEY_EXCHANGE_METHOD: + return key_exchange_method_names; case EXTENDED_SEQUENCE_NUMBERS: return extended_sequence_numbers_names; case EXTENDED_OUTPUT_FUNCTION: diff --git a/src/libstrongswan/crypto/transform.h b/src/libstrongswan/crypto/transform.h index 2848aa028..e96ee8ca7 100644 --- a/src/libstrongswan/crypto/transform.h +++ b/src/libstrongswan/crypto/transform.h @@ -33,7 +33,7 @@ enum transform_type_t { ENCRYPTION_ALGORITHM = 1, PSEUDO_RANDOM_FUNCTION = 2, INTEGRITY_ALGORITHM = 3, - DIFFIE_HELLMAN_GROUP = 4, + KEY_EXCHANGE_METHOD = 4, EXTENDED_SEQUENCE_NUMBERS = 5, HASH_ALGORITHM = 256, RANDOM_NUMBER_GENERATOR = 257, diff --git a/src/libstrongswan/plugins/botan/botan_diffie_hellman.c b/src/libstrongswan/plugins/botan/botan_diffie_hellman.c index a55711d1b..cacc220d6 100644 --- a/src/libstrongswan/plugins/botan/botan_diffie_hellman.c +++ b/src/libstrongswan/plugins/botan/botan_diffie_hellman.c @@ -49,12 +49,17 @@ struct private_botan_diffie_hellman_t { /** * Diffie Hellman group number */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * Private key */ - botan_privkey_t dh_key; + botan_privkey_t key; + + /** + * Public key value provided by peer + */ + chunk_t pubkey; /** * Diffie hellman shared secret @@ -84,8 +89,8 @@ bool load_private_key(private_botan_diffie_hellman_t *this, chunk_t value) return FALSE; } - if (botan_privkey_destroy(this->dh_key) || - botan_privkey_load_dh(&this->dh_key, this->p, this->g, xa)) + if (botan_privkey_destroy(this->key) || + botan_privkey_load_dh(&this->key, this->p, this->g, xa)) { botan_mp_destroy(xa); return FALSE; @@ -94,33 +99,33 @@ bool load_private_key(private_botan_diffie_hellman_t *this, chunk_t value) return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_botan_diffie_hellman_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } - chunk_clear(&this->shared_secret); - - return botan_dh_key_derivation(this->dh_key, value, &this->shared_secret); + chunk_clear(&this->pubkey); + this->pubkey = chunk_clone(value); + return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_botan_diffie_hellman_t *this, chunk_t *value) { *value = chunk_empty; /* get key size of public key first */ - if (botan_pk_op_key_agreement_export_public(this->dh_key, NULL, &value->len) + if (botan_pk_op_key_agreement_export_public(this->key, NULL, &value->len) != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE) { return FALSE; } *value = chunk_alloc(value->len); - if (botan_pk_op_key_agreement_export_public(this->dh_key, value->ptr, + if (botan_pk_op_key_agreement_export_public(this->key, value->ptr, &value->len)) { chunk_clear(value); @@ -129,17 +134,18 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_botan_diffie_hellman_t *this, chunk_t value) { chunk_clear(&this->shared_secret); return load_private_key(this, value); } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_botan_diffie_hellman_t *this, chunk_t *secret) { - if (!this->shared_secret.len) + if (!this->shared_secret.len && + !botan_dh_key_derivation(this->key, this->pubkey, &this->shared_secret)) { return FALSE; } @@ -147,26 +153,27 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_botan_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_botan_diffie_hellman_t *this) { botan_mp_destroy(this->p); botan_mp_destroy(this->g); - botan_privkey_destroy(this->dh_key); + botan_privkey_destroy(this->key); chunk_clear(&this->shared_secret); + chunk_clear(&this->pubkey); free(this); } /* * Generic internal constructor */ -static botan_diffie_hellman_t *create_generic(diffie_hellman_group_t group, +static botan_diffie_hellman_t *create_generic(key_exchange_method_t group, chunk_t g, chunk_t p, size_t exp_len) { private_botan_diffie_hellman_t *this; @@ -175,12 +182,12 @@ static botan_diffie_hellman_t *create_generic(diffie_hellman_group_t group, INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, @@ -222,7 +229,7 @@ static botan_diffie_hellman_t *create_generic(diffie_hellman_group_t group, * Described in header. */ botan_diffie_hellman_t *botan_diffie_hellman_create( - diffie_hellman_group_t group, ...) + key_exchange_method_t group, ...) { diffie_hellman_params_t *params; chunk_t g, p; diff --git a/src/libstrongswan/plugins/botan/botan_diffie_hellman.h b/src/libstrongswan/plugins/botan/botan_diffie_hellman.h index 84408229f..1a5bd0007 100644 --- a/src/libstrongswan/plugins/botan/botan_diffie_hellman.h +++ b/src/libstrongswan/plugins/botan/botan_diffie_hellman.h @@ -32,7 +32,7 @@ typedef struct botan_diffie_hellman_t botan_diffie_hellman_t; -#include +#include /** * Implementation of the Diffie-Hellman algorithm using Botan. @@ -40,20 +40,20 @@ typedef struct botan_diffie_hellman_t botan_diffie_hellman_t; struct botan_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new botan_diffie_hellman_t object. * - * @param group Diffie Hellman group number to use + * @param group Diffie-Hellman group number to use * @param ... expects generator and prime as chunk_t if MODP_CUSTOM * @return botan_diffie_hellman_t object, * NULL if not supported */ botan_diffie_hellman_t *botan_diffie_hellman_create( - diffie_hellman_group_t group, ...); + key_exchange_method_t group, ...); #endif /** BOTAN_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.c b/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.c index 18e9cb1c1..5ebaca4c4 100644 --- a/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.c @@ -48,7 +48,7 @@ struct private_botan_ec_diffie_hellman_t { /** * Diffie Hellman group */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * EC curve name @@ -60,29 +60,32 @@ struct private_botan_ec_diffie_hellman_t { */ botan_privkey_t key; + /** + * Public key value provided by peer + */ + chunk_t pubkey; + /** * Shared secret */ chunk_t shared_secret; }; -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_botan_ec_diffie_hellman_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } - chunk_clear(&this->shared_secret); - + chunk_clear(&this->pubkey); /* prepend 0x04 to indicate uncompressed point format */ - value = chunk_cata("cc", chunk_from_chars(0x04), value); - - return botan_dh_key_derivation(this->key, value, &this->shared_secret); + this->pubkey = chunk_cat("cc", chunk_from_chars(0x04), value); + return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_botan_ec_diffie_hellman_t *this, chunk_t *value) { chunk_t pkey = chunk_empty; @@ -104,7 +107,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_botan_ec_diffie_hellman_t *this, chunk_t value) { botan_mp_t scalar; @@ -132,10 +135,11 @@ METHOD(diffie_hellman_t, set_private_value, bool, return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_botan_ec_diffie_hellman_t *this, chunk_t *secret) { - if (!this->shared_secret.len) + if (!this->shared_secret.len && + !botan_dh_key_derivation(this->key, this->pubkey, &this->shared_secret)) { return FALSE; } @@ -143,17 +147,18 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_botan_ec_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_botan_ec_diffie_hellman_t *this) { botan_privkey_destroy(this->key); chunk_clear(&this->shared_secret); + chunk_clear(&this->pubkey); free(this); } @@ -161,19 +166,19 @@ METHOD(diffie_hellman_t, destroy, void, * Described in header. */ botan_ec_diffie_hellman_t *botan_ec_diffie_hellman_create( - diffie_hellman_group_t group) + key_exchange_method_t group) { private_botan_ec_diffie_hellman_t *this; botan_rng_t rng; INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, diff --git a/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.h b/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.h index 0ba832ed3..c5fc96895 100644 --- a/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.h +++ b/src/libstrongswan/plugins/botan/botan_ec_diffie_hellman.h @@ -39,18 +39,18 @@ typedef struct botan_ec_diffie_hellman_t botan_ec_diffie_hellman_t; struct botan_ec_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new botan_ec_diffie_hellman_t object. * - * @param group EC Diffie Hellman group number to use + * @param group EC Diffie-Hellman group number to use * @return botan_ec_diffie_hellman_t object, NULL if not supported */ botan_ec_diffie_hellman_t *botan_ec_diffie_hellman_create( - diffie_hellman_group_t group); + key_exchange_method_t group); #endif /** BOTAN_EC_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/botan/botan_plugin.c b/src/libstrongswan/plugins/botan/botan_plugin.c index 9a79b2197..3fe329765 100644 --- a/src/libstrongswan/plugins/botan/botan_plugin.c +++ b/src/libstrongswan/plugins/botan/botan_plugin.c @@ -74,33 +74,33 @@ METHOD(plugin_t, get_features, int, #ifdef BOTAN_HAS_DIFFIE_HELLMAN /* MODP DH groups */ - PLUGIN_REGISTER(DH, botan_diffie_hellman_create), - PLUGIN_PROVIDE(DH, MODP_3072_BIT), - PLUGIN_PROVIDE(DH, MODP_4096_BIT), - PLUGIN_PROVIDE(DH, MODP_6144_BIT), - PLUGIN_PROVIDE(DH, MODP_8192_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_224), - PLUGIN_PROVIDE(DH, MODP_2048_256), - PLUGIN_PROVIDE(DH, MODP_1536_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_160), - PLUGIN_PROVIDE(DH, MODP_768_BIT), - PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_REGISTER(KE, botan_diffie_hellman_create), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), + PLUGIN_PROVIDE(KE, MODP_4096_BIT), + PLUGIN_PROVIDE(KE, MODP_6144_BIT), + PLUGIN_PROVIDE(KE, MODP_8192_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_224), + PLUGIN_PROVIDE(KE, MODP_2048_256), + PLUGIN_PROVIDE(KE, MODP_1536_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_160), + PLUGIN_PROVIDE(KE, MODP_768_BIT), + PLUGIN_PROVIDE(KE, MODP_CUSTOM), #endif #ifdef BOTAN_HAS_ECDH /* EC DH groups */ - PLUGIN_REGISTER(DH, botan_ec_diffie_hellman_create), - PLUGIN_PROVIDE(DH, ECP_256_BIT), - PLUGIN_PROVIDE(DH, ECP_384_BIT), - PLUGIN_PROVIDE(DH, ECP_521_BIT), - PLUGIN_PROVIDE(DH, ECP_256_BP), - PLUGIN_PROVIDE(DH, ECP_384_BP), - PLUGIN_PROVIDE(DH, ECP_512_BP), + PLUGIN_REGISTER(KE, botan_ec_diffie_hellman_create), + PLUGIN_PROVIDE(KE, ECP_256_BIT), + PLUGIN_PROVIDE(KE, ECP_384_BIT), + PLUGIN_PROVIDE(KE, ECP_521_BIT), + PLUGIN_PROVIDE(KE, ECP_256_BP), + PLUGIN_PROVIDE(KE, ECP_384_BP), + PLUGIN_PROVIDE(KE, ECP_512_BP), #endif #ifdef BOTAN_HAS_X25519 - PLUGIN_REGISTER(DH, botan_x25519_create), - PLUGIN_PROVIDE(DH, CURVE_25519), + PLUGIN_REGISTER(KE, botan_x25519_create), + PLUGIN_PROVIDE(KE, CURVE_25519), #endif /* crypters */ diff --git a/src/libstrongswan/plugins/botan/botan_x25519.c b/src/libstrongswan/plugins/botan/botan_x25519.c index 1c2c2231f..8323e555d 100644 --- a/src/libstrongswan/plugins/botan/botan_x25519.c +++ b/src/libstrongswan/plugins/botan/botan_x25519.c @@ -42,33 +42,38 @@ struct private_diffie_hellman_t { /** * Public interface */ - diffie_hellman_t public; + key_exchange_t public; /** * Private key */ botan_privkey_t key; + /** + * Public key value provided by peer + */ + chunk_t pubkey; + /** * Shared secret */ chunk_t shared_secret; }; -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_diffie_hellman_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(CURVE_25519, value)) + if (!key_exchange_verify_pubkey(CURVE_25519, value)) { return FALSE; } - chunk_clear(&this->shared_secret); - - return botan_dh_key_derivation(this->key, value, &this->shared_secret); + chunk_clear(&this->pubkey); + this->pubkey = chunk_clone(value); + return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_diffie_hellman_t *this, chunk_t *value) { value->len = 0; @@ -88,7 +93,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_diffie_hellman_t *this, chunk_t value) { if (value.len != 32) @@ -110,10 +115,11 @@ METHOD(diffie_hellman_t, set_private_value, bool, return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_diffie_hellman_t *this, chunk_t *secret) { - if (!this->shared_secret.len) + if (!this->shared_secret.len && + !botan_dh_key_derivation(this->key, this->pubkey, &this->shared_secret)) { return FALSE; } @@ -121,24 +127,25 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_diffie_hellman_t *this) { return CURVE_25519; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_diffie_hellman_t *this) { botan_privkey_destroy(this->key); chunk_clear(&this->shared_secret); + chunk_clear(&this->pubkey); free(this); } /* * Described in header */ -diffie_hellman_t *botan_x25519_create(diffie_hellman_group_t group) +key_exchange_t *botan_x25519_create(key_exchange_method_t ke) { private_diffie_hellman_t *this; botan_rng_t rng; @@ -146,10 +153,10 @@ diffie_hellman_t *botan_x25519_create(diffie_hellman_group_t group) INIT(this, .public = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, ); diff --git a/src/libstrongswan/plugins/botan/botan_x25519.h b/src/libstrongswan/plugins/botan/botan_x25519.h index 069d3bbcf..692978b9c 100644 --- a/src/libstrongswan/plugins/botan/botan_x25519.h +++ b/src/libstrongswan/plugins/botan/botan_x25519.h @@ -33,9 +33,9 @@ /** * Creates a new X25519 implementation using Botan. * - * @param group DH group, must be CURVE_25519 + * @param ke key exchange method, must be CURVE_25519 * @return object, NULL if not supported */ -diffie_hellman_t *botan_x25519_create(diffie_hellman_group_t group); +key_exchange_t *botan_x25519_create(key_exchange_method_t ke); #endif /** BOTAN_X25519_H_ @}*/ diff --git a/src/libstrongswan/plugins/curve25519/curve25519_dh.c b/src/libstrongswan/plugins/curve25519/curve25519_dh.c index b3f3e49d6..5d489d413 100644 --- a/src/libstrongswan/plugins/curve25519/curve25519_dh.c +++ b/src/libstrongswan/plugins/curve25519/curve25519_dh.c @@ -42,6 +42,11 @@ struct private_curve25519_dh_t { */ bool computed; + /** + * Public key provided by peer + */ + u_char pubkey[CURVE25519_KEY_SIZE]; + /** * Curve25519 backend */ @@ -73,21 +78,18 @@ static bool generate_key(private_curve25519_dh_t *this) return this->drv->set_key(this->drv, key); } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_curve25519_dh_t *this, chunk_t value) { if (value.len == CURVE25519_KEY_SIZE) { - if (this->drv->curve25519(this->drv, value.ptr, this->shared)) - { - this->computed = TRUE; - return TRUE; - } + memcpy(this->pubkey, value.ptr, value.len); + return TRUE; } return FALSE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_curve25519_dh_t *this, chunk_t *value) { u_char basepoint[CURVE25519_KEY_SIZE] = { 9 }; @@ -101,7 +103,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return FALSE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_curve25519_dh_t *this, chunk_t value) { if (value.len != CURVE25519_KEY_SIZE) @@ -111,24 +113,26 @@ METHOD(diffie_hellman_t, set_private_value, bool, return this->drv->set_key(this->drv, value.ptr); } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_curve25519_dh_t *this, chunk_t *secret) { - if (!this->computed) + if (!this->computed && + !this->drv->curve25519(this->drv, this->pubkey, this->shared)) { return FALSE; } + this->computed = TRUE; *secret = chunk_clone(chunk_from_thing(this->shared)); return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_curve25519_dh_t *this) { return CURVE_25519; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_curve25519_dh_t *this) { this->drv->destroy(this->drv); @@ -138,7 +142,7 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header. */ -curve25519_dh_t *curve25519_dh_create(diffie_hellman_group_t group) +curve25519_dh_t *curve25519_dh_create(key_exchange_method_t group) { private_curve25519_dh_t *this; @@ -149,12 +153,12 @@ curve25519_dh_t *curve25519_dh_create(diffie_hellman_group_t group) INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, diff --git a/src/libstrongswan/plugins/curve25519/curve25519_dh.h b/src/libstrongswan/plugins/curve25519/curve25519_dh.h index 9c31d1a7a..8b11b3155 100644 --- a/src/libstrongswan/plugins/curve25519/curve25519_dh.h +++ b/src/libstrongswan/plugins/curve25519/curve25519_dh.h @@ -32,9 +32,9 @@ typedef struct curve25519_dh_t curve25519_dh_t; struct curve25519_dh_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** @@ -43,6 +43,6 @@ struct curve25519_dh_t { * @param group DH group, CURVE_25519 * @return curve25519_dh_t object, NULL on error */ -curve25519_dh_t *curve25519_dh_create(diffie_hellman_group_t group); +curve25519_dh_t *curve25519_dh_create(key_exchange_method_t group); #endif /** CURVE25519_DH_H_ @}*/ diff --git a/src/libstrongswan/plugins/curve25519/curve25519_plugin.c b/src/libstrongswan/plugins/curve25519/curve25519_plugin.c index d2028fed6..7afe4e9e2 100644 --- a/src/libstrongswan/plugins/curve25519/curve25519_plugin.c +++ b/src/libstrongswan/plugins/curve25519/curve25519_plugin.c @@ -47,8 +47,8 @@ METHOD(plugin_t, get_features, int, { static plugin_feature_t f[] = { /* X25519 DH group */ - PLUGIN_REGISTER(DH, curve25519_dh_create), - PLUGIN_PROVIDE(DH, CURVE_25519), + PLUGIN_REGISTER(KE, curve25519_dh_create), + PLUGIN_PROVIDE(KE, CURVE_25519), PLUGIN_DEPENDS(RNG, RNG_STRONG), /* Ed25519 private/public keys */ PLUGIN_REGISTER(PRIVKEY, curve25519_private_key_load, TRUE), diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c index b28128695..7da1df313 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c @@ -36,7 +36,7 @@ struct private_gcrypt_dh_t { /** * Diffie Hellman group number */ - diffie_hellman_group_t group; + key_exchange_method_t group; /* * Generator value @@ -74,13 +74,13 @@ struct private_gcrypt_dh_t { size_t p_len; }; -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_gcrypt_dh_t *this, chunk_t value) { gcry_mpi_t p_min_1; gcry_error_t err; - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } @@ -100,25 +100,22 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, p_min_1 = gcry_mpi_new(this->p_len * 8); gcry_mpi_sub_ui(p_min_1, this->p, 1); - /* check public value: - * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1 - * 2. a public value larger or equal the modulus is invalid */ - if (gcry_mpi_cmp_ui(this->yb, 1) > 0 && - gcry_mpi_cmp(this->yb, p_min_1) < 0) + /* check that the public value y satisfies 1 < y < p-1. + * according to RFC 6989, section 2.1, this is enough for the common safe- + * prime DH groups (i.e. with q=(p-1)/2 being prime) and also for those + * with small subgroups (22, 23, 24) if private keys are not reused, which + * we never do and explicitly prevent by not resetting this->zz when a + * different public key is set. */ + if (gcry_mpi_cmp_ui(this->yb, 1) <= 0 || + gcry_mpi_cmp(this->yb, p_min_1) >= 0) { - if (!this->zz) - { - this->zz = gcry_mpi_new(this->p_len * 8); - } - gcry_mpi_powm(this->zz, this->yb, this->xa, this->p); - } - else - { - DBG1(DBG_LIB, "public DH value verification failed:" - " y < 2 || y > p - 1 "); + DBG1(DBG_LIB, "public DH value verification failed: " + "y <= 1 || y >= p - 1"); + gcry_mpi_release(p_min_1); + return FALSE; } gcry_mpi_release(p_min_1); - return this->zz != NULL; + return TRUE; } /** @@ -139,14 +136,14 @@ static chunk_t export_mpi(gcry_mpi_t value, size_t len) return chunk; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_gcrypt_dh_t *this, chunk_t *value) { *value = export_mpi(this->ya, this->p_len); return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_gcrypt_dh_t *this, chunk_t value) { gcry_error_t err; @@ -164,24 +161,25 @@ METHOD(diffie_hellman_t, set_private_value, bool, return !err; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_gcrypt_dh_t *this, chunk_t *secret) { if (!this->zz) { - return FALSE; + this->zz = gcry_mpi_new(this->p_len * 8); + gcry_mpi_powm(this->zz, this->yb, this->xa, this->p); } *secret = export_mpi(this->zz, this->p_len); return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_gcrypt_dh_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_gcrypt_dh_t *this) { gcry_mpi_release(this->p); @@ -196,7 +194,7 @@ METHOD(diffie_hellman_t, destroy, void, /* * Generic internal constructor */ -static gcrypt_dh_t *create_generic(diffie_hellman_group_t group, size_t exp_len, +static gcrypt_dh_t *create_generic(key_exchange_method_t group, size_t exp_len, chunk_t g, chunk_t p) { private_gcrypt_dh_t *this; @@ -206,12 +204,12 @@ static gcrypt_dh_t *create_generic(diffie_hellman_group_t group, size_t exp_len, INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, @@ -273,7 +271,7 @@ static gcrypt_dh_t *create_generic(diffie_hellman_group_t group, size_t exp_len, /* * Described in header. */ -gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group) +gcrypt_dh_t *gcrypt_dh_create(key_exchange_method_t group) { diffie_hellman_params_t *params; @@ -290,7 +288,7 @@ gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group) /* * Described in header. */ -gcrypt_dh_t *gcrypt_dh_create_custom(diffie_hellman_group_t group, ...) +gcrypt_dh_t *gcrypt_dh_create_custom(key_exchange_method_t group, ...) { if (group == MODP_CUSTOM) { diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h index 891613f2c..755a3b8e8 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h @@ -32,9 +32,9 @@ typedef struct gcrypt_dh_t gcrypt_dh_t; struct gcrypt_dh_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** @@ -43,7 +43,7 @@ struct gcrypt_dh_t { * @param group Diffie Hellman group number to use * @return gcrypt_dh_t object, NULL if not supported */ -gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group); +gcrypt_dh_t *gcrypt_dh_create(key_exchange_method_t group); /** * Creates a new gcrypt_dh_t object for MODP_CUSTOM. @@ -52,7 +52,7 @@ gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group); * @param ... expects generator and prime as chunk_t * @return gcrypt_dh_t object, NULL if not supported */ -gcrypt_dh_t *gcrypt_dh_create_custom(diffie_hellman_group_t group, ...); +gcrypt_dh_t *gcrypt_dh_create_custom(key_exchange_method_t group, ...); #endif /** GCRYPT_DH_H_ @}*/ diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c index 7c88996d1..8d9b7a305 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c @@ -106,20 +106,20 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(HASHER, HASH_SHA384), PLUGIN_PROVIDE(HASHER, HASH_SHA512), /* MODP DH groups */ - PLUGIN_REGISTER(DH, gcrypt_dh_create), - PLUGIN_PROVIDE(DH, MODP_3072_BIT), - PLUGIN_PROVIDE(DH, MODP_4096_BIT), - PLUGIN_PROVIDE(DH, MODP_6144_BIT), - PLUGIN_PROVIDE(DH, MODP_8192_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_224), - PLUGIN_PROVIDE(DH, MODP_2048_256), - PLUGIN_PROVIDE(DH, MODP_1536_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_160), - PLUGIN_PROVIDE(DH, MODP_768_BIT), - PLUGIN_REGISTER(DH, gcrypt_dh_create_custom), - PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_REGISTER(KE, gcrypt_dh_create), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), + PLUGIN_PROVIDE(KE, MODP_4096_BIT), + PLUGIN_PROVIDE(KE, MODP_6144_BIT), + PLUGIN_PROVIDE(KE, MODP_8192_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_224), + PLUGIN_PROVIDE(KE, MODP_2048_256), + PLUGIN_PROVIDE(KE, MODP_1536_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_160), + PLUGIN_PROVIDE(KE, MODP_768_BIT), + PLUGIN_REGISTER(KE, gcrypt_dh_create_custom), + PLUGIN_PROVIDE(KE, MODP_CUSTOM), /* RSA private/public key loading */ PLUGIN_REGISTER(PUBKEY, gcrypt_rsa_public_key_load, TRUE), PLUGIN_PROVIDE(PUBKEY, KEY_RSA), diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c index 90b58411a..6528495a5 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c @@ -41,7 +41,7 @@ struct private_gmp_diffie_hellman_t { /** * Diffie Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /* * Generator value. @@ -84,12 +84,12 @@ struct private_gmp_diffie_hellman_t { bool computed; }; -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_gmp_diffie_hellman_t *this, chunk_t value) { mpz_t p_min_1; - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } @@ -97,59 +97,33 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, mpz_init(p_min_1); mpz_sub_ui(p_min_1, this->p, 1); + /* this->computed is not reset in order to prevent reuse of this DH + * instance (see below) */ mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr); - /* check public value: - * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1 - * 2. a public value larger or equal the modulus is invalid */ - if (mpz_cmp_ui(this->yb, 1) > 0 && - mpz_cmp(this->yb, p_min_1) < 0) + /* check that the public value y satisfies 1 < y < p-1. + * according to RFC 6989, section 2.1, this is enough for the common safe- + * prime DH groups (i.e. with q=(p-1)/2 being prime), only for those with + * small subgroups (22, 23, 24) does the RFC require the extended test but + * only if private keys are reused. we never do that anyway and it's + * explicitly prevented in this implementation. so the extended test, which + * optionally happens in get_shared_secret(), is really only useful for full + * NIST SP 800-56A compliance, which only allows the partial check for + * safe-prime groups. + */ + if (mpz_cmp_ui(this->yb, 1) <= 0 || + mpz_cmp(this->yb, p_min_1) >= 0) { -#ifdef EXTENDED_DH_TEST - /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */ - mpz_t q, one; - diffie_hellman_params_t *params; - - mpz_init(q); - mpz_init(one); - - params = diffie_hellman_get_params(this->group); - if (!params->subgroup.len) - { - mpz_fdiv_q_2exp(q, p_min_1, 1); - } - else - { - mpz_import(q, params->subgroup.len, 1, 1, 1, 0, params->subgroup.ptr); - } - mpz_powm(one, this->yb, q, this->p); - mpz_clear(q); - if (mpz_cmp_ui(one, 1) == 0) - { - mpz_powm(this->zz, this->yb, this->xa, this->p); - this->computed = TRUE; - } - else - { - DBG1(DBG_LIB, "public DH value verification failed:" - " y ^ q mod p != 1"); - } - mpz_clear(one); -#else - mpz_powm(this->zz, this->yb, this->xa, this->p); - this->computed = TRUE; -#endif - } - else - { - DBG1(DBG_LIB, "public DH value verification failed:" - " y < 2 || y > p - 1 "); + DBG1(DBG_LIB, "public DH value verification failed: " + "y <= 1 || y >= p - 1"); + mpz_clear(p_min_1); + return FALSE; } mpz_clear(p_min_1); - return this->computed; + return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_gmp_diffie_hellman_t *this,chunk_t *value) { value->len = this->p_len; @@ -161,7 +135,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_gmp_diffie_hellman_t *this, chunk_t value) { mpz_import(this->xa, value.len, 1, 1, 1, 0, value.ptr); @@ -170,12 +144,46 @@ METHOD(diffie_hellman_t, set_private_value, bool, return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_gmp_diffie_hellman_t *this, chunk_t *secret) { if (!this->computed) { - return FALSE; +#ifdef EXTENDED_DH_TEST + /* test if y ^ q mod p = 1, where q = (p - 1)/2 or the actual size of + * the subgroup. as noted above, this check is not really necessary as + * the plugin does not reuse private keys */ + mpz_t q, one, p_min_1; + diffie_hellman_params_t *params; + + mpz_init(q); + mpz_init(one); + + params = diffie_hellman_get_params(this->group); + if (!params->subgroup.len) + { + mpz_init(p_min_1); + mpz_sub_ui(p_min_1, this->p, 1); + mpz_fdiv_q_2exp(q, p_min_1, 1); + mpz_clear(p_min_1); + } + else + { + mpz_import(q, params->subgroup.len, 1, 1, 1, 0, params->subgroup.ptr); + } + mpz_powm(one, this->yb, q, this->p); + mpz_clear(q); + if (mpz_cmp_ui(one, 1) != 0) + { + DBG1(DBG_LIB, "public DH value verification failed: " + "y ^ q mod p != 1"); + mpz_clear(one); + return FALSE; + } + mpz_clear(one); +#endif + mpz_powm(this->zz, this->yb, this->xa, this->p); + this->computed = TRUE; } secret->len = this->p_len; secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz); @@ -186,13 +194,13 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_gmp_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_gmp_diffie_hellman_t *this) { mpz_clear(this->p); @@ -207,7 +215,7 @@ METHOD(diffie_hellman_t, destroy, void, /** * Generic internal constructor */ -static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group, +static gmp_diffie_hellman_t *create_generic(key_exchange_method_t group, size_t exp_len, chunk_t g, chunk_t p) { private_gmp_diffie_hellman_t *this; @@ -216,12 +224,12 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group, INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, @@ -273,7 +281,7 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group, /* * Described in header */ -gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group) +gmp_diffie_hellman_t *gmp_diffie_hellman_create(key_exchange_method_t group) { diffie_hellman_params_t *params; @@ -290,7 +298,7 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group) * Described in header */ gmp_diffie_hellman_t *gmp_diffie_hellman_create_custom( - diffie_hellman_group_t group, ...) + key_exchange_method_t group, ...) { if (group == MODP_CUSTOM) { diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h index 3f1becf23..fca3ee482 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h @@ -31,9 +31,9 @@ typedef struct gmp_diffie_hellman_t gmp_diffie_hellman_t; struct gmp_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** @@ -42,7 +42,7 @@ struct gmp_diffie_hellman_t { * @param group Diffie Hellman group number to use * @return gmp_diffie_hellman_t object, NULL if not supported */ -gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group); +gmp_diffie_hellman_t *gmp_diffie_hellman_create(key_exchange_method_t group); /** * Creates a new gmp_diffie_hellman_t object for MODP_CUSTOM. @@ -52,7 +52,7 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group); * @return gmp_diffie_hellman_t object, NULL if not supported */ gmp_diffie_hellman_t *gmp_diffie_hellman_create_custom( - diffie_hellman_group_t group, ...); + key_exchange_method_t group, ...); #endif /** GMP_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c index e2373c694..4d0934929 100644 --- a/src/libstrongswan/plugins/gmp/gmp_plugin.c +++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c @@ -43,31 +43,31 @@ METHOD(plugin_t, get_features, int, { static plugin_feature_t f[] = { /* DH groups */ - PLUGIN_REGISTER(DH, gmp_diffie_hellman_create), - PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_REGISTER(KE, gmp_diffie_hellman_create), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_4096_BIT), + PLUGIN_PROVIDE(KE, MODP_4096_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_6144_BIT), + PLUGIN_PROVIDE(KE, MODP_6144_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_8192_BIT), + PLUGIN_PROVIDE(KE, MODP_8192_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_2048_224), + PLUGIN_PROVIDE(KE, MODP_2048_224), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_2048_256), + PLUGIN_PROVIDE(KE, MODP_2048_256), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_1536_BIT), + PLUGIN_PROVIDE(KE, MODP_1536_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_1024_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_1024_160), + PLUGIN_PROVIDE(KE, MODP_1024_160), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_PROVIDE(DH, MODP_768_BIT), + PLUGIN_PROVIDE(KE, MODP_768_BIT), PLUGIN_DEPENDS(RNG, RNG_STRONG), - PLUGIN_REGISTER(DH, gmp_diffie_hellman_create_custom), - PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_REGISTER(KE, gmp_diffie_hellman_create_custom), + PLUGIN_PROVIDE(KE, MODP_CUSTOM), PLUGIN_DEPENDS(RNG, RNG_STRONG), /* private/public keys */ PLUGIN_REGISTER(PRIVKEY, gmp_rsa_private_key_load, TRUE), diff --git a/src/libstrongswan/plugins/newhope/newhope_ke.c b/src/libstrongswan/plugins/newhope/newhope_ke.c index 8e9ce7bda..7e784d42e 100644 --- a/src/libstrongswan/plugins/newhope/newhope_ke.c +++ b/src/libstrongswan/plugins/newhope/newhope_ke.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include static const int seed_len = 32; /* 256 bits */ @@ -278,7 +278,7 @@ static uint8_t* unpack_rec(private_newhope_ke_t *this, uint8_t *x) return r; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_newhope_ke_t *this, chunk_t *value) { uint16_t n, q; @@ -397,7 +397,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, } } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_newhope_ke_t *this, chunk_t *secret) { if (this->shared_secret.len == 0) @@ -410,7 +410,7 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_newhope_ke_t *this, chunk_t value) { newhope_reconciliation_t * rec; @@ -436,7 +436,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, if (value.len != poly_len + seed_len) { DBG1(DBG_LIB, "received %N KE payload of incorrect size", - diffie_hellman_group_names, NH_128_BIT); + key_exchange_method_names, NH_128_BIT); return FALSE; } a_seed = chunk_create(value.ptr + poly_len, seed_len); @@ -545,7 +545,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, if (value.len != poly_len + rec_len) { DBG1(DBG_LIB, "received %N KE payload of incorrect size", - diffie_hellman_group_names, NH_128_BIT); + key_exchange_method_names, NH_128_BIT); return FALSE; } @@ -581,13 +581,13 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, } } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_newhope_ke_t *this) { return NH_128_BIT; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_newhope_ke_t *this) { chunk_clear(&this->shared_secret); @@ -601,17 +601,17 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header. */ -newhope_ke_t *newhope_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) +newhope_ke_t *newhope_ke_create(key_exchange_method_t ke, chunk_t g, chunk_t p) { private_newhope_ke_t *this; INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .get_method = _get_method, .destroy = _destroy, }, }, diff --git a/src/libstrongswan/plugins/newhope/newhope_ke.h b/src/libstrongswan/plugins/newhope/newhope_ke.h index 9a4f43edb..d0188b241 100644 --- a/src/libstrongswan/plugins/newhope/newhope_ke.h +++ b/src/libstrongswan/plugins/newhope/newhope_ke.h @@ -32,20 +32,20 @@ typedef struct newhope_ke_t newhope_ke_t; struct newhope_ke_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new newhope_ke_t object. * - * @param group New Hope DH group number + * @param ke New Hope key exchange number * @param g not used * @param p not used * @return newhope_ke_t object, NULL if not supported */ -newhope_ke_t *newhope_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p); +newhope_ke_t *newhope_ke_create(key_exchange_method_t ke, chunk_t g, chunk_t p); #endif /** NEWHOPE_KE_H_ @}*/ diff --git a/src/libstrongswan/plugins/newhope/newhope_plugin.c b/src/libstrongswan/plugins/newhope/newhope_plugin.c index c198dce13..de930226e 100644 --- a/src/libstrongswan/plugins/newhope/newhope_plugin.c +++ b/src/libstrongswan/plugins/newhope/newhope_plugin.c @@ -42,8 +42,8 @@ METHOD(plugin_t, get_features, int, private_newhope_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { - PLUGIN_REGISTER(DH, newhope_ke_create), - PLUGIN_PROVIDE(DH, NH_128_BIT), + PLUGIN_REGISTER(KE, newhope_ke_create), + PLUGIN_PROVIDE(KE, NH_128_BIT), PLUGIN_DEPENDS(XOF, XOF_SHAKE_128), PLUGIN_DEPENDS(XOF, XOF_CHACHA20), }; diff --git a/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c b/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c index 41ea6ab64..c5911cfa9 100644 --- a/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c +++ b/src/libstrongswan/plugins/newhope/tests/suites/test_newhope_ke.c @@ -27,7 +27,7 @@ const int count = 1000; START_TEST(test_newhope_ke_good) { chunk_t i_msg, r_msg, i_shared_secret, r_shared_secret; - diffie_hellman_t *i_nh, *r_nh; + key_exchange_t *i_nh, *r_nh; struct timespec start, stop; int i; @@ -35,24 +35,24 @@ START_TEST(test_newhope_ke_good) for (i = 0; i < count; i++) { - i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + i_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(i_nh != NULL); - ck_assert(i_nh->get_dh_group(i_nh) == NH_128_BIT); + ck_assert(i_nh->get_method(i_nh) == NH_128_BIT); - ck_assert(i_nh->get_my_public_value(i_nh, &i_msg)); + ck_assert(i_nh->get_public_key(i_nh, &i_msg)); ck_assert(i_msg.len = 1824); - r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + r_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(r_nh != NULL); - ck_assert(r_nh->set_other_public_value(r_nh, i_msg)); - ck_assert(r_nh->get_my_public_value(r_nh, &r_msg)); + ck_assert(r_nh->set_public_key(r_nh, i_msg)); + ck_assert(r_nh->get_public_key(r_nh, &r_msg)); ck_assert(r_msg.len == 2048); ck_assert(r_nh->get_shared_secret(r_nh, &r_shared_secret)); ck_assert(r_shared_secret.len == 32); - ck_assert(i_nh->set_other_public_value(i_nh, r_msg)); + ck_assert(i_nh->set_public_key(i_nh, r_msg)); ck_assert(i_nh->get_shared_secret(i_nh, &i_shared_secret)); ck_assert(i_shared_secret.len == 32); ck_assert(chunk_equals(i_shared_secret, r_shared_secret)); @@ -77,26 +77,26 @@ END_TEST START_TEST(test_newhope_ke_wrong) { chunk_t i_msg, r_msg, i_shared_secret, r_shared_secret; - diffie_hellman_t *i_nh, *r_nh; + key_exchange_t *i_nh, *r_nh; - i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + i_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(i_nh != NULL); - ck_assert(i_nh->get_my_public_value(i_nh, &i_msg)); + ck_assert(i_nh->get_public_key(i_nh, &i_msg)); - r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + r_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(r_nh != NULL); - ck_assert(r_nh->set_other_public_value(r_nh, i_msg)); - ck_assert(r_nh->get_my_public_value(r_nh, &r_msg)); + ck_assert(r_nh->set_public_key(r_nh, i_msg)); + ck_assert(r_nh->get_public_key(r_nh, &r_msg)); /* destroy 1st instance of i_nh */ i_nh->destroy(i_nh); chunk_free(&i_msg); /* create 2nd instance of i_nh */ - i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + i_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(i_nh != NULL); - ck_assert(i_nh->get_my_public_value(i_nh, &i_msg)); - ck_assert(i_nh->set_other_public_value(i_nh, r_msg)); + ck_assert(i_nh->get_public_key(i_nh, &i_msg)); + ck_assert(i_nh->set_public_key(i_nh, r_msg)); ck_assert(r_nh->get_shared_secret(r_nh, &r_shared_secret)); ck_assert(i_nh->get_shared_secret(i_nh, &i_shared_secret)); @@ -114,7 +114,7 @@ END_TEST START_TEST(test_newhope_ke_fail_i) { - diffie_hellman_t *i_nh; + key_exchange_t *i_nh; char buf_ff[2048]; int i; @@ -131,10 +131,10 @@ START_TEST(test_newhope_ke_fail_i) for (i = 0; i < countof(r_msg); i++) { - i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + i_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(i_nh != NULL); - ck_assert(i_nh->get_my_public_value(i_nh, &i_msg)); - ck_assert(!i_nh->set_other_public_value(i_nh, r_msg[i])); + ck_assert(i_nh->get_public_key(i_nh, &i_msg)); + ck_assert(!i_nh->set_public_key(i_nh, r_msg[i])); chunk_free(&i_msg); i_nh->destroy(i_nh); } @@ -143,7 +143,7 @@ END_TEST START_TEST(test_newhope_ke_fail_r) { - diffie_hellman_t *r_nh; + key_exchange_t *r_nh; char buf_ff[1824]; int i; @@ -158,9 +158,9 @@ START_TEST(test_newhope_ke_fail_r) for (i = 0; i < countof(i_msg); i++) { - r_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); + r_nh = lib->crypto->create_ke(lib->crypto, NH_128_BIT); ck_assert(r_nh != NULL); - ck_assert(!r_nh->set_other_public_value(r_nh, i_msg[i])); + ck_assert(!r_nh->set_public_key(r_nh, i_msg[i])); r_nh->destroy(r_nh); } } diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.c b/src/libstrongswan/plugins/ntru/ntru_ke.c index 9f8a70a11..bedf41a3b 100644 --- a/src/libstrongswan/plugins/ntru/ntru_ke.c +++ b/src/libstrongswan/plugins/ntru/ntru_ke.c @@ -17,7 +17,7 @@ #include "ntru_private_key.h" #include "ntru_public_key.h" -#include +#include #include #include @@ -55,7 +55,7 @@ struct private_ntru_ke_t { /** * Diffie Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * NTRU Parameter Set @@ -108,7 +108,7 @@ struct private_ntru_ke_t { drbg_t *drbg; }; -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_ntru_ke_t *this, chunk_t *value) { *value = chunk_empty; @@ -139,7 +139,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_ntru_ke_t *this, chunk_t *secret) { if (!this->computed || !this->shared_secret.len) @@ -152,7 +152,7 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_ntru_ke_t *this, chunk_t value) { if (this->privkey) @@ -218,13 +218,13 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, return this->computed; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_ntru_ke_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_ntru_ke_t *this) { DESTROY_IF(this->privkey); @@ -238,7 +238,7 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header. */ -ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) +ntru_ke_t *ntru_ke_create(key_exchange_method_t group, chunk_t g, chunk_t p) { private_ntru_ke_t *this; const ntru_param_set_id_t *param_sets; @@ -311,11 +311,11 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .get_method = _get_method, .destroy = _destroy, }, }, diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.h b/src/libstrongswan/plugins/ntru/ntru_ke.h index c0b4634c2..2b2a667e4 100644 --- a/src/libstrongswan/plugins/ntru/ntru_ke.h +++ b/src/libstrongswan/plugins/ntru/ntru_ke.h @@ -30,9 +30,9 @@ typedef struct ntru_ke_t ntru_ke_t; struct ntru_ke_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** @@ -43,7 +43,7 @@ struct ntru_ke_t { * @param p not used * @return ntru_ke_t object, NULL if not supported */ -ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p); +ntru_ke_t *ntru_ke_create(key_exchange_method_t group, chunk_t g, chunk_t p); #endif /** NTRU_KE_H_ @}*/ diff --git a/src/libstrongswan/plugins/ntru/ntru_plugin.c b/src/libstrongswan/plugins/ntru/ntru_plugin.c index 0cf3fe564..ccf888b03 100644 --- a/src/libstrongswan/plugins/ntru/ntru_plugin.c +++ b/src/libstrongswan/plugins/ntru/ntru_plugin.c @@ -40,20 +40,20 @@ METHOD(plugin_t, get_features, int, private_ntru_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { - PLUGIN_REGISTER(DH, ntru_ke_create), - PLUGIN_PROVIDE(DH, NTRU_112_BIT), + PLUGIN_REGISTER(KE, ntru_ke_create), + PLUGIN_PROVIDE(KE, NTRU_112_BIT), PLUGIN_DEPENDS(RNG, RNG_TRUE), PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256), PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA1), - PLUGIN_PROVIDE(DH, NTRU_128_BIT), + PLUGIN_PROVIDE(KE, NTRU_128_BIT), PLUGIN_DEPENDS(RNG, RNG_TRUE), PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256), PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA1), - PLUGIN_PROVIDE(DH, NTRU_192_BIT), + PLUGIN_PROVIDE(KE, NTRU_192_BIT), PLUGIN_DEPENDS(RNG, RNG_TRUE), PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256), PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA256), - PLUGIN_PROVIDE(DH, NTRU_256_BIT), + PLUGIN_PROVIDE(KE, NTRU_256_BIT), PLUGIN_DEPENDS(RNG, RNG_TRUE), PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256), PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA256), diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c index e1cea1709..5f9d01996 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c @@ -54,7 +54,7 @@ struct private_openssl_diffie_hellman_t { /** * Diffie Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; #if OPENSSL_VERSION_NUMBER >= 0x30000000L /** @@ -84,13 +84,13 @@ struct private_openssl_diffie_hellman_t { chunk_t shared_secret; }; -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_openssl_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_openssl_diffie_hellman_t *this, chunk_t *value) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -115,7 +115,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, #endif } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_openssl_diffie_hellman_t *this, chunk_t *secret) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -151,10 +151,10 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_openssl_diffie_hellman_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } @@ -204,7 +204,7 @@ static BIGNUM *calculate_public_key(BIGNUM *priv, const BIGNUM *g, return pub; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_openssl_diffie_hellman_t *this, chunk_t value) { BIGNUM *priv, *g = NULL, *p = NULL, *pub = NULL; @@ -254,7 +254,7 @@ error: #else /* OPENSSL_VERSION_NUMBER */ -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_openssl_diffie_hellman_t *this, chunk_t value) { BIGNUM *privkey; @@ -274,7 +274,7 @@ METHOD(diffie_hellman_t, set_private_value, bool, #endif /* OPENSSL_VERSION_NUMBER */ -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_openssl_diffie_hellman_t *this) { #if OPENSSL_VERSION_NUMBER >= 0x30000000L @@ -292,7 +292,7 @@ METHOD(diffie_hellman_t, destroy, void, * Described in header. */ openssl_diffie_hellman_t *openssl_diffie_hellman_create( - diffie_hellman_group_t group, ...) + key_exchange_method_t group, ...) { private_openssl_diffie_hellman_t *this; BIGNUM *g, *p; @@ -300,12 +300,12 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create( INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h index 8c56ff2ac..d9ffbf2f5 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h @@ -32,20 +32,20 @@ typedef struct openssl_diffie_hellman_t openssl_diffie_hellman_t; struct openssl_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new openssl_diffie_hellman_t object. * - * @param group Diffie Hellman group number to use + * @param group Diffie-Hellman group number to use * @param ... expects generator and prime as chunk_t if MODP_CUSTOM * @return openssl_diffie_hellman_t object, NULL if not supported */ openssl_diffie_hellman_t *openssl_diffie_hellman_create( - diffie_hellman_group_t group, ...); + key_exchange_method_t group, ...); #endif /** OPENSSL_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c index 00b9f9359..34f681d65 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c @@ -54,7 +54,7 @@ struct private_openssl_ec_diffie_hellman_t { /** * Diffie Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * EC private (public) key @@ -198,10 +198,10 @@ error: } #endif /* OPENSSL_VERSION_NUMBER < ... */ -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } @@ -232,7 +232,7 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t *value) { #if OPENSSL_VERSION_NUMBER < 0x1010000fL @@ -253,7 +253,7 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, #endif } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t *secret) { if (!this->shared_secret.len && @@ -266,7 +266,7 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_openssl_ec_diffie_hellman_t *this) { return this->group; @@ -275,7 +275,7 @@ METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, /* * Described in header */ -int openssl_ecdh_group_to_nid(diffie_hellman_group_t group) +int openssl_ecdh_group_to_nid(key_exchange_method_t group) { switch (group) { @@ -337,7 +337,7 @@ static bool ecp2chunk(EC_GROUP *group, EC_POINT *point, chunk_t *chunk) return chunk->len; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t value) { BIGNUM *priv = NULL; @@ -390,7 +390,7 @@ METHOD(diffie_hellman_t, set_private_value, bool, #else /* OPENSSL_VERSION_NUMBER */ -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t value) { EC_KEY *key = NULL; @@ -430,7 +430,7 @@ error: #endif /* OPENSSL_VERSION_NUMBER */ -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_openssl_ec_diffie_hellman_t *this) { EC_GROUP_free(this->ec_group); @@ -443,7 +443,7 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header */ -openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group) +openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(key_exchange_method_t group) { private_openssl_ec_diffie_hellman_t *this; int curve; @@ -456,12 +456,12 @@ openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_gro INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h index da62df65a..627a7bf76 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h @@ -32,18 +32,19 @@ typedef struct openssl_ec_diffie_hellman_t openssl_ec_diffie_hellman_t; struct openssl_ec_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new openssl_ec_diffie_hellman_t object. * - * @param group EC Diffie Hellman group number to use - * @return openssl_ec_diffie_hellman_t object, NULL if not supported + * @param group EC Diffie-Hellman group number to use + * @return openssl_ec_diffie_hellman_t object, NULL if unsupported */ -openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group); +openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create( + key_exchange_method_t group); /** * Map ECDH groups to OpenSSL NIDs for the ECC curve. @@ -51,6 +52,6 @@ openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_gro * @param group ECDH group * @return NID for the curve */ -int openssl_ecdh_group_to_nid(diffie_hellman_group_t group); +int openssl_ecdh_group_to_nid(key_exchange_method_t group); #endif /** OPENSSL_EC_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index 42465d76e..972d63e35 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -326,7 +326,7 @@ METHOD(plugin_t, get_name, char*, * Check if the given DH group is in the list of supported curves. */ static bool ecdh_group_supported(EC_builtin_curve *curves, size_t num_curves, - diffie_hellman_group_t group) + key_exchange_method_t group) { int j; @@ -360,7 +360,7 @@ static void add_ecdh_features(plugin_feature_t *features, for (i = 0; i < count; i++) { if (to_add[i].kind != FEATURE_PROVIDE || - ecdh_group_supported(curves, num_curves, to_add[i].arg.dh_group)) + ecdh_group_supported(curves, num_curves, to_add[i].arg.ke)) { features[(*pos)++] = to_add[i]; } @@ -528,19 +528,19 @@ METHOD(plugin_t, get_features, int, #endif /* OPENSSL_VERSION_NUMBER */ #ifndef OPENSSL_NO_DH /* MODP DH groups */ - PLUGIN_REGISTER(DH, openssl_diffie_hellman_create), - PLUGIN_PROVIDE(DH, MODP_3072_BIT), - PLUGIN_PROVIDE(DH, MODP_4096_BIT), - PLUGIN_PROVIDE(DH, MODP_6144_BIT), - PLUGIN_PROVIDE(DH, MODP_8192_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_224), - PLUGIN_PROVIDE(DH, MODP_2048_256), - PLUGIN_PROVIDE(DH, MODP_1536_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_160), - PLUGIN_PROVIDE(DH, MODP_768_BIT), - PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_REGISTER(KE, openssl_diffie_hellman_create), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), + PLUGIN_PROVIDE(KE, MODP_4096_BIT), + PLUGIN_PROVIDE(KE, MODP_6144_BIT), + PLUGIN_PROVIDE(KE, MODP_8192_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_224), + PLUGIN_PROVIDE(KE, MODP_2048_256), + PLUGIN_PROVIDE(KE, MODP_1536_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_160), + PLUGIN_PROVIDE(KE, MODP_768_BIT), + PLUGIN_PROVIDE(KE, MODP_CUSTOM), #endif #ifndef OPENSSL_NO_RSA /* RSA private/public key loading */ @@ -649,11 +649,11 @@ METHOD(plugin_t, get_features, int, #endif #endif /* OPENSSL_NO_ECDSA */ #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_ECDH) - PLUGIN_REGISTER(DH, openssl_x_diffie_hellman_create), + PLUGIN_REGISTER(KE, openssl_x_diffie_hellman_create), /* available since 1.1.0a, but we require 1.1.1 features */ - PLUGIN_PROVIDE(DH, CURVE_25519), + PLUGIN_PROVIDE(KE, CURVE_25519), /* available since 1.1.1 */ - PLUGIN_PROVIDE(DH, CURVE_448), + PLUGIN_PROVIDE(KE, CURVE_448), #endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_ECDH */ #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) /* EdDSA private/public key loading */ @@ -686,17 +686,17 @@ METHOD(plugin_t, get_features, int, static plugin_feature_t f_ecdh[] = { #ifndef OPENSSL_NO_ECDH /* EC DH groups */ - PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create), - PLUGIN_PROVIDE(DH, ECP_256_BIT), - PLUGIN_PROVIDE(DH, ECP_384_BIT), - PLUGIN_PROVIDE(DH, ECP_521_BIT), - PLUGIN_PROVIDE(DH, ECP_224_BIT), - PLUGIN_PROVIDE(DH, ECP_192_BIT), + PLUGIN_REGISTER(KE, openssl_ec_diffie_hellman_create), + PLUGIN_PROVIDE(KE, ECP_256_BIT), + PLUGIN_PROVIDE(KE, ECP_384_BIT), + PLUGIN_PROVIDE(KE, ECP_521_BIT), + PLUGIN_PROVIDE(KE, ECP_224_BIT), + PLUGIN_PROVIDE(KE, ECP_192_BIT), #if OPENSSL_VERSION_NUMBER >= 0x10002000L - PLUGIN_PROVIDE(DH, ECP_256_BP), - PLUGIN_PROVIDE(DH, ECP_384_BP), - PLUGIN_PROVIDE(DH, ECP_512_BP), - PLUGIN_PROVIDE(DH, ECP_224_BP), + PLUGIN_PROVIDE(KE, ECP_256_BP), + PLUGIN_PROVIDE(KE, ECP_384_BP), + PLUGIN_PROVIDE(KE, ECP_512_BP), + PLUGIN_PROVIDE(KE, ECP_224_BP), #endif /* OPENSSL_VERSION_NUMBER */ #endif /* OPENSSL_NO_ECDH */ }; diff --git a/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c index 88fed10f1..16b5740a2 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.c @@ -25,21 +25,21 @@ #include -typedef struct private_diffie_hellman_t private_diffie_hellman_t; +typedef struct private_key_exchange_t private_key_exchange_t; /** * Private data */ -struct private_diffie_hellman_t { +struct private_key_exchange_t { /** * Public interface. */ - diffie_hellman_t public; + key_exchange_t public; /** - * Diffie Hellman group number. + * Key exchange method. */ - diffie_hellman_group_t group; + key_exchange_method_t ke; /** * Private (public) key @@ -58,11 +58,11 @@ struct private_diffie_hellman_t { }; /** - * Map a DH group to a key type + * Map a key exchange method to a key type */ -static int map_key_type(diffie_hellman_group_t group) +static int map_key_type(key_exchange_method_t ke) { - switch (group) + switch (ke) { case CURVE_25519: return EVP_PKEY_X25519; @@ -73,29 +73,29 @@ static int map_key_type(diffie_hellman_group_t group) } } -METHOD(diffie_hellman_t, set_other_public_value, bool, - private_diffie_hellman_t *this, chunk_t value) +METHOD(key_exchange_t, set_public_key, bool, + private_key_exchange_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->ke, value)) { return FALSE; } EVP_PKEY_free(this->pub); - this->pub = EVP_PKEY_new_raw_public_key(map_key_type(this->group), NULL, + this->pub = EVP_PKEY_new_raw_public_key(map_key_type(this->ke), NULL, value.ptr, value.len); if (!this->pub) { DBG1(DBG_LIB, "%N public value is malformed", - diffie_hellman_group_names, this->group); + key_exchange_method_names, this->ke); return FALSE; } chunk_clear(&this->shared_secret); return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, - private_diffie_hellman_t *this, chunk_t *value) +METHOD(key_exchange_t, get_public_key, bool, + private_key_exchange_t *this, chunk_t *value) { size_t len; @@ -114,11 +114,11 @@ METHOD(diffie_hellman_t, get_my_public_value, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, - private_diffie_hellman_t *this, chunk_t value) +METHOD(key_exchange_t, set_private_key, bool, + private_key_exchange_t *this, chunk_t value) { EVP_PKEY_free(this->key); - this->key = EVP_PKEY_new_raw_private_key(map_key_type(this->group), NULL, + this->key = EVP_PKEY_new_raw_private_key(map_key_type(this->ke), NULL, value.ptr, value.len); if (!this->key) { @@ -127,28 +127,28 @@ METHOD(diffie_hellman_t, set_private_value, bool, return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, - private_diffie_hellman_t *this, chunk_t *secret) +METHOD(key_exchange_t, get_shared_secret, bool, + private_key_exchange_t *this, chunk_t *secret) { if (!this->shared_secret.len && !openssl_compute_shared_key(this->key, this->pub, &this->shared_secret)) { DBG1(DBG_LIB, "%N shared secret computation failed", - diffie_hellman_group_names, this->group); + key_exchange_method_names, this->ke); return FALSE; } *secret = chunk_clone(this->shared_secret); return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, - private_diffie_hellman_t *this) +METHOD(key_exchange_t, get_method, key_exchange_method_t, + private_key_exchange_t *this) { - return this->group; + return this->ke; } -METHOD(diffie_hellman_t, destroy, void, - private_diffie_hellman_t *this) +METHOD(key_exchange_t, destroy, void, + private_key_exchange_t *this) { EVP_PKEY_free(this->key); EVP_PKEY_free(this->pub); @@ -159,13 +159,13 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header */ -diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group) +key_exchange_t *openssl_x_diffie_hellman_create(key_exchange_method_t ke) { - private_diffie_hellman_t *this; + private_key_exchange_t *this; EVP_PKEY_CTX *ctx = NULL; EVP_PKEY *key = NULL; - switch (group) + switch (ke) { case CURVE_25519: ctx = EVP_PKEY_CTX_new_id(NID_X25519, NULL); @@ -182,7 +182,7 @@ diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group) EVP_PKEY_keygen(ctx, &key) <= 0) { DBG1(DBG_LIB, "generating key for %N failed", - diffie_hellman_group_names, group); + key_exchange_method_names, ke); EVP_PKEY_CTX_free(ctx); return NULL; } @@ -191,13 +191,13 @@ diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group) INIT(this, .public = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, - .group = group, + .ke = ke, .key = key, ); return &this->public; diff --git a/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h index de1bfce39..1a92ed3b1 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h +++ b/src/libstrongswan/plugins/openssl/openssl_x_diffie_hellman.h @@ -27,12 +27,12 @@ #include /** - * Creates a new diffie_hellman_t object. + * Creates a new key_exchange_t object. * - * @param group Diffie Hellman group number to use + * @param ke key exchange method to use * @return object, NULL if not supported */ -diffie_hellman_t *openssl_x_diffie_hellman_create(diffie_hellman_group_t group); +key_exchange_t *openssl_x_diffie_hellman_create(key_exchange_method_t ke); #endif /** OPENSSL_X_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c index d12602318..a75cec674 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c @@ -46,9 +46,9 @@ struct private_pkcs11_dh_t { CK_SESSION_HANDLE session; /** - * Diffie Hellman group number. + * Diffie-Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * Handle for own private value @@ -60,6 +60,11 @@ struct private_pkcs11_dh_t { */ chunk_t pub_key; + /** + * Public value provided by peer + */ + chunk_t other; + /** * Shared secret */ @@ -114,14 +119,15 @@ static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other) return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_pkcs11_dh_t *this, chunk_t value) { - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } + chunk_clear(&this->other); switch (this->group) { case ECP_192_BIT: @@ -140,26 +146,28 @@ METHOD(diffie_hellman_t, set_other_public_value, bool, pubkey.len, pubkey.ptr, }; - value = chunk_from_thing(params); + this->other = chunk_clone(chunk_from_thing(params)); break; } default: + this->other = chunk_clone(value); break; } - return derive_secret(this, value); + return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_pkcs11_dh_t *this, chunk_t *value) { *value = chunk_clone(this->pub_key); return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_pkcs11_dh_t *this, chunk_t *secret) { - if (!this->secret.ptr) + if (!this->secret.ptr && + !derive_secret(this, this->other)) { return FALSE; } @@ -167,18 +175,19 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_pkcs11_dh_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_pkcs11_dh_t *this) { this->lib->f->C_CloseSession(this->session); chunk_clear(&this->pub_key); chunk_clear(&this->secret); + chunk_clear(&this->other); free(this); } @@ -316,7 +325,7 @@ static pkcs11_library_t *find_token(private_pkcs11_dh_t *this, /** * Generic internal constructor */ -static private_pkcs11_dh_t *create_generic(diffie_hellman_group_t group, +static private_pkcs11_dh_t *create_generic(key_exchange_method_t group, CK_MECHANISM_TYPE key, CK_MECHANISM_TYPE derive) { @@ -324,11 +333,11 @@ static private_pkcs11_dh_t *create_generic(diffie_hellman_group_t group, INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .get_method = _get_method, .destroy = _destroy, }, }, @@ -346,7 +355,7 @@ static private_pkcs11_dh_t *create_generic(diffie_hellman_group_t group, return this; } -static pkcs11_dh_t *create_ecp(diffie_hellman_group_t group, chunk_t ecparam) +static pkcs11_dh_t *create_ecp(key_exchange_method_t group, chunk_t ecparam) { private_pkcs11_dh_t *this = create_generic(group, CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE); @@ -367,7 +376,7 @@ static pkcs11_dh_t *create_ecp(diffie_hellman_group_t group, chunk_t ecparam) /** * Constructor for MODP DH */ -static pkcs11_dh_t *create_modp(diffie_hellman_group_t group, size_t exp_len, +static pkcs11_dh_t *create_modp(key_exchange_method_t group, size_t exp_len, chunk_t g, chunk_t p) { private_pkcs11_dh_t *this = create_generic(group, CKM_DH_PKCS_KEY_PAIR_GEN, @@ -387,7 +396,7 @@ static pkcs11_dh_t *create_modp(diffie_hellman_group_t group, size_t exp_len, /** * Lookup the EC params for the given group. */ -static chunk_t ecparams_lookup(diffie_hellman_group_t group) +static chunk_t ecparams_lookup(key_exchange_method_t group) { switch (group) { @@ -410,7 +419,7 @@ static chunk_t ecparams_lookup(diffie_hellman_group_t group) /** * Described in header. */ -pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, ...) +pkcs11_dh_t *pkcs11_dh_create(key_exchange_method_t group, ...) { switch (group) { diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h index 9ce410cbd..660745fce 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h @@ -32,19 +32,19 @@ typedef struct pkcs11_dh_t pkcs11_dh_t; struct pkcs11_dh_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new pkcs11_dh_t object. * - * @param group Diffie Hellman group number to use + * @param group Diffie-Hellman group number to use * @param ... expects generator and prime as chunk_t if MODP_CUSTOM * @return pkcs11_dh_t object, NULL if not supported */ -pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, ...); +pkcs11_dh_t *pkcs11_dh_create(key_exchange_method_t group, ...); #endif /** PKCS11_DH_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c index 2b710d6e2..72b5ddd2f 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c @@ -197,27 +197,27 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(HASHER, HASH_SHA512), }; static plugin_feature_t f_dh[] = { - PLUGIN_REGISTER(DH, pkcs11_dh_create), - PLUGIN_PROVIDE(DH, MODP_2048_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_224), - PLUGIN_PROVIDE(DH, MODP_2048_256), - PLUGIN_PROVIDE(DH, MODP_1536_BIT), - PLUGIN_PROVIDE(DH, MODP_3072_BIT), - PLUGIN_PROVIDE(DH, MODP_4096_BIT), - PLUGIN_PROVIDE(DH, MODP_6144_BIT), - PLUGIN_PROVIDE(DH, MODP_8192_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_160), - PLUGIN_PROVIDE(DH, MODP_768_BIT), - PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_REGISTER(KE, pkcs11_dh_create), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_224), + PLUGIN_PROVIDE(KE, MODP_2048_256), + PLUGIN_PROVIDE(KE, MODP_1536_BIT), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), + PLUGIN_PROVIDE(KE, MODP_4096_BIT), + PLUGIN_PROVIDE(KE, MODP_6144_BIT), + PLUGIN_PROVIDE(KE, MODP_8192_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_160), + PLUGIN_PROVIDE(KE, MODP_768_BIT), + PLUGIN_PROVIDE(KE, MODP_CUSTOM), }; static plugin_feature_t f_ecdh[] = { - PLUGIN_REGISTER(DH, pkcs11_dh_create), - PLUGIN_PROVIDE(DH, ECP_192_BIT), - PLUGIN_PROVIDE(DH, ECP_224_BIT), - PLUGIN_PROVIDE(DH, ECP_256_BIT), - PLUGIN_PROVIDE(DH, ECP_384_BIT), - PLUGIN_PROVIDE(DH, ECP_521_BIT), + PLUGIN_REGISTER(KE, pkcs11_dh_create), + PLUGIN_PROVIDE(KE, ECP_192_BIT), + PLUGIN_PROVIDE(KE, ECP_224_BIT), + PLUGIN_PROVIDE(KE, ECP_256_BIT), + PLUGIN_PROVIDE(KE, ECP_384_BIT), + PLUGIN_PROVIDE(KE, ECP_521_BIT), }; static plugin_feature_t f_rng[] = { PLUGIN_REGISTER(RNG, pkcs11_rng_create), diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c index de8486197..075230ab0 100644 --- a/src/libstrongswan/plugins/plugin_feature.c +++ b/src/libstrongswan/plugins/plugin_feature.c @@ -33,7 +33,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM, "XOF", "KDF", "DRBG", - "DH", + "KE", "RNG", "NONCE_GEN", "PRIVKEY", @@ -99,8 +99,8 @@ uint32_t plugin_feature_hash(plugin_feature_t *feature) case FEATURE_DRBG: data = chunk_from_thing(feature->arg.drbg); break; - case FEATURE_DH: - data = chunk_from_thing(feature->arg.dh_group); + case FEATURE_KE: + data = chunk_from_thing(feature->arg.ke); break; case FEATURE_PRIVKEY: data = chunk_from_thing(feature->arg.privkey); @@ -178,8 +178,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b) return a->arg.kdf == b->arg.kdf; case FEATURE_DRBG: return a->arg.drbg == b->arg.drbg; - case FEATURE_DH: - return a->arg.dh_group == b->arg.dh_group; + case FEATURE_KE: + return a->arg.ke == b->arg.ke; case FEATURE_RNG: return a->arg.rng_quality <= b->arg.rng_quality; case FEATURE_NONCE_GEN: @@ -239,7 +239,7 @@ bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b) case FEATURE_XOF: case FEATURE_KDF: case FEATURE_DRBG: - case FEATURE_DH: + case FEATURE_KE: case FEATURE_NONCE_GEN: case FEATURE_RESOLVER: case FEATURE_PRIVKEY: @@ -347,9 +347,9 @@ char* plugin_feature_get_string(plugin_feature_t *feature) return str; } break; - case FEATURE_DH: + case FEATURE_KE: if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, - diffie_hellman_group_names, feature->arg.dh_group) > 0) + key_exchange_method_names, feature->arg.ke) > 0) { return str; } @@ -530,8 +530,8 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature, lib->crypto->add_drbg(lib->crypto, feature->arg.drbg, name, reg->arg.reg.f); break; - case FEATURE_DH: - lib->crypto->add_dh(lib->crypto, feature->arg.dh_group, + case FEATURE_KE: + lib->crypto->add_ke(lib->crypto, feature->arg.ke, name, reg->arg.reg.f); break; case FEATURE_RNG: @@ -635,8 +635,8 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature, case FEATURE_DRBG: lib->crypto->remove_drbg(lib->crypto, reg->arg.reg.f); break; - case FEATURE_DH: - lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f); + case FEATURE_KE: + lib->crypto->remove_ke(lib->crypto, reg->arg.reg.f); break; case FEATURE_RNG: lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f); diff --git a/src/libstrongswan/plugins/plugin_feature.h b/src/libstrongswan/plugins/plugin_feature.h index 9c3b45290..12ea78a63 100644 --- a/src/libstrongswan/plugins/plugin_feature.h +++ b/src/libstrongswan/plugins/plugin_feature.h @@ -116,8 +116,8 @@ struct plugin_feature_t { FEATURE_KDF, /** drbg_t */ FEATURE_DRBG, - /** diffie_hellman_t */ - FEATURE_DH, + /** key_exchange_t */ + FEATURE_KE, /** rng_t */ FEATURE_RNG, /** nonce_gen_t */ @@ -185,8 +185,8 @@ struct plugin_feature_t { drbg_type_t drbg; /** FEATURE_HASHER */ hash_algorithm_t hasher; - /** FEATURE_DH */ - diffie_hellman_group_t dh_group; + /** FEATURE_KE */ + key_exchange_method_t ke; /** FEATURE_RNG */ rng_quality_t rng_quality; /** FEATURE_PRIVKEY */ @@ -293,7 +293,7 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_XOF(kind, alg) __PLUGIN_FEATURE(kind, XOF, .xof = alg) #define _PLUGIN_FEATURE_KDF(kind, alg) __PLUGIN_FEATURE(kind, KDF, .kdf = alg) #define _PLUGIN_FEATURE_DRBG(kind, type) __PLUGIN_FEATURE(kind, DRBG, .drbg = type) -#define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group) +#define _PLUGIN_FEATURE_KE(kind, method) __PLUGIN_FEATURE(kind, KE, .ke = method) #define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality) #define _PLUGIN_FEATURE_NONCE_GEN(kind, ...) __PLUGIN_FEATURE(kind, NONCE_GEN, .custom = NULL) #define _PLUGIN_FEATURE_PRIVKEY(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type) @@ -328,7 +328,7 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_REGISTER_XOF(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_KDF(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_DRBG(type, f) __PLUGIN_FEATURE_REGISTER(type, f) -#define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_KE(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_NONCE_GEN(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h index 2a9023229..8e34d14e0 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors.h +++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h @@ -352,26 +352,26 @@ TEST_VECTOR_RNG(rng_runs_1) TEST_VECTOR_RNG(rng_runs_2) TEST_VECTOR_RNG(rng_runs_3) -TEST_VECTOR_DH(modp768) -TEST_VECTOR_DH(modp1024) -TEST_VECTOR_DH(modp1536) -TEST_VECTOR_DH(modp2048) -TEST_VECTOR_DH(modp3072) -TEST_VECTOR_DH(modp4096) -TEST_VECTOR_DH(modp6144) -TEST_VECTOR_DH(modp8192) -TEST_VECTOR_DH(modp1024_160) -TEST_VECTOR_DH(modp2048_224) -TEST_VECTOR_DH(modp2048_256) -TEST_VECTOR_DH(ecp192) -TEST_VECTOR_DH(ecp224) -TEST_VECTOR_DH(ecp256) -TEST_VECTOR_DH(ecp384) -TEST_VECTOR_DH(ecp521) -TEST_VECTOR_DH(ecp224bp) -TEST_VECTOR_DH(ecp256bp) -TEST_VECTOR_DH(ecp384bp) -TEST_VECTOR_DH(ecp512bp) -TEST_VECTOR_DH(curve25519_1) -TEST_VECTOR_DH(curve25519_2) -TEST_VECTOR_DH(curve448_1) +TEST_VECTOR_KE(modp768) +TEST_VECTOR_KE(modp1024) +TEST_VECTOR_KE(modp1536) +TEST_VECTOR_KE(modp2048) +TEST_VECTOR_KE(modp3072) +TEST_VECTOR_KE(modp4096) +TEST_VECTOR_KE(modp6144) +TEST_VECTOR_KE(modp8192) +TEST_VECTOR_KE(modp1024_160) +TEST_VECTOR_KE(modp2048_224) +TEST_VECTOR_KE(modp2048_256) +TEST_VECTOR_KE(ecp192) +TEST_VECTOR_KE(ecp224) +TEST_VECTOR_KE(ecp256) +TEST_VECTOR_KE(ecp384) +TEST_VECTOR_KE(ecp521) +TEST_VECTOR_KE(ecp224bp) +TEST_VECTOR_KE(ecp256bp) +TEST_VECTOR_KE(ecp384bp) +TEST_VECTOR_KE(ecp512bp) +TEST_VECTOR_KE(curve25519_1) +TEST_VECTOR_KE(curve25519_2) +TEST_VECTOR_KE(curve448_1) diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c b/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c index cc53bdfe2..8ce1d8ae1 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/curve25519.c @@ -19,8 +19,8 @@ /** * From RFC 7748 */ -dh_test_vector_t curve25519_1 = { - .group = CURVE_25519, .priv_len = 32, .pub_len = 32, .shared_len = 32, +ke_test_vector_t curve25519_1 = { + .method = CURVE_25519, .priv_len = 32, .pub_len = 32, .shared_len = 32, .priv_a = "\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45" "\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a", .priv_b = "\x5d\xab\x08\x7e\x62\x4a\x8a\x4b\x79\xe1\x7f\x8b\x83\x80\x0e\xe6" @@ -36,8 +36,8 @@ dh_test_vector_t curve25519_1 = { /** * From RFC 8031 */ -dh_test_vector_t curve25519_2 = { - .group = CURVE_25519, .priv_len = 32, .pub_len = 32, .shared_len = 32, +ke_test_vector_t curve25519_2 = { + .method = CURVE_25519, .priv_len = 32, .pub_len = 32, .shared_len = 32, .priv_a = "\x75\x1f\xb4\x30\x86\x55\xb4\x76\xb6\x78\x9b\x73\x25\xf9\xea\x8c" "\xdd\xd1\x6a\x58\x53\x3f\xf6\xd9\xe6\x00\x09\x46\x4a\x5f\x9d\x94", .priv_b = "\x0a\x54\x64\x52\x53\x29\x0d\x60\xdd\xad\xd0\xe0\x30\xba\xcd\x9e" diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c b/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c index da9fb9ac0..b8ee7647f 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/curve448.c @@ -19,8 +19,8 @@ /** * From RFC 7748 */ -dh_test_vector_t curve448_1 = { - .group = CURVE_448, .priv_len = 56, .pub_len = 56, .shared_len = 56, +ke_test_vector_t curve448_1 = { + .method = CURVE_448, .priv_len = 56, .pub_len = 56, .shared_len = 56, .priv_a = "\x9a\x8f\x49\x25\xd1\x51\x9f\x57\x75\xcf\x46\xb0\x4b\x58\x00\xd4" "\xee\x9e\xe8\xba\xe8\xbc\x55\x65\xd4\x98\xc2\x8d\xd9\xc9\xba\xf5" "\x74\xa9\x41\x97\x44\x89\x73\x91\x00\x63\x82\xa6\xf1\x27\xab\x1d" diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/ecp.c b/src/libstrongswan/plugins/test_vectors/test_vectors/ecp.c index 378d4b2c5..ccf572d1e 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/ecp.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/ecp.c @@ -20,8 +20,8 @@ * Test vectors from RFC5114 */ -dh_test_vector_t ecp192 = { - .group = ECP_192_BIT, .priv_len = 24, .pub_len = 48, .shared_len = 24, +ke_test_vector_t ecp192 = { + .method = ECP_192_BIT, .priv_len = 24, .pub_len = 48, .shared_len = 24, .priv_a = "\x32\x3f\xa3\x16\x9d\x8e\x9c\x65\x93\xf5\x94\x76\xbc\x14\x20\x00" "\xab\x5b\xe0\xe2\x49\xc4\x34\x26", .priv_b = "\x63\x1f\x95\xbb\x4a\x67\x63\x2c\x9c\x47\x6e\xee\x9a\xb6\x95\xab" @@ -36,8 +36,8 @@ dh_test_vector_t ecp192 = { "\xe5\xff\x4f\x83\x7f\x54\xfe\xbe", }; -dh_test_vector_t ecp224 = { - .group = ECP_224_BIT, .priv_len = 28, .pub_len = 56, .shared_len = 28, +ke_test_vector_t ecp224 = { + .method = ECP_224_BIT, .priv_len = 28, .pub_len = 56, .shared_len = 28, .priv_a = "\xb5\x58\xeb\x6c\x28\x8d\xa7\x07\xbb\xb4\xf8\xfb\xae\x2a\xb9\xe9" "\xcb\x62\xe3\xbc\x5c\x75\x73\xe2\x2e\x26\xd3\x7f", .priv_b = "\xac\x3b\x1a\xdd\x3d\x97\x70\xe6\xf6\xa7\x08\xee\x9f\x3b\x8e\x0a" @@ -54,8 +54,8 @@ dh_test_vector_t ecp224 = { "\xd9\x6e\xcc\x3b\x6d\xc1\x71\x4a\x4e\xa9\x49\xfa", }; -dh_test_vector_t ecp256 = { - .group = ECP_256_BIT, .priv_len = 32, .pub_len = 64, .shared_len = 32, +ke_test_vector_t ecp256 = { + .method = ECP_256_BIT, .priv_len = 32, .pub_len = 64, .shared_len = 32, .priv_a = "\x81\x42\x64\x14\x5f\x2f\x56\xf2\xe9\x6a\x8e\x33\x7a\x12\x84\x99" "\x3f\xaf\x43\x2a\x5a\xbc\xe5\x9e\x86\x7b\x72\x91\xd5\x07\xa3\xaf", .priv_b = "\x2c\xe1\x78\x8e\xc1\x97\xe0\x96\xdb\x95\xa2\x00\xcc\x0a\xb2\x6a" @@ -72,8 +72,8 @@ dh_test_vector_t ecp256 = { "\xf5\x81\x1e\x9d\xc8\xec\x8e\xea\x7f\x80\xd2\x1c\x82\x0c\x27\x88", }; -dh_test_vector_t ecp384 = { - .group = ECP_384_BIT, .priv_len = 48, .pub_len = 96, .shared_len = 48, +ke_test_vector_t ecp384 = { + .method = ECP_384_BIT, .priv_len = 48, .pub_len = 96, .shared_len = 48, .priv_a = "\xd2\x73\x35\xea\x71\x66\x4a\xf2\x44\xdd\x14\xe9\xfd\x12\x60\x71" "\x5d\xfd\x8a\x79\x65\x57\x1c\x48\xd7\x09\xee\x7a\x79\x62\xa1\x56" "\xd7\x06\xa9\x0c\xbc\xb5\xdf\x29\x86\xf0\x5f\xea\xdb\x93\x76\xf1", @@ -97,8 +97,8 @@ dh_test_vector_t ecp384 = { "\x27\xaa\x8a\x45\x40\x88\x4c\x37\xde\x15\x9a\x58\x02\x8a\xbc\x0e", }; -dh_test_vector_t ecp521 = { - .group = ECP_521_BIT, .priv_len = 66, .pub_len = 132, .shared_len = 66, +ke_test_vector_t ecp521 = { + .method = ECP_521_BIT, .priv_len = 66, .pub_len = 132, .shared_len = 66, .priv_a = "\x01\x13\xf8\x2d\xa8\x25\x73\x5e\x3d\x97\x27\x66\x83\xb2\xb7\x42" "\x77\xba\xd2\x73\x35\xea\x71\x66\x4a\xf2\x43\x0c\xc4\xf3\x34\x59" "\xb9\x66\x9e\xe7\x8b\x3f\xfb\x9b\x86\x83\x01\x5d\x34\x4d\xcb\xfe" diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/ecpbp.c b/src/libstrongswan/plugins/test_vectors/test_vectors/ecpbp.c index 4af280690..b50e3f288 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/ecpbp.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/ecpbp.c @@ -20,8 +20,8 @@ * Test vectors from RFC6923/RFC7027 */ -dh_test_vector_t ecp224bp = { - .group = ECP_224_BP, .priv_len = 28, .pub_len = 56, .shared_len = 28, +ke_test_vector_t ecp224bp = { + .method = ECP_224_BP, .priv_len = 28, .pub_len = 56, .shared_len = 28, .priv_a = "\x7c\x4b\x7a\x2c\x8a\x4b\xad\x1f\xbb\x7d\x79\xcc\x09\x55\xdb\x7c" "\x6a\x46\x60\xca\x64\xcc\x47\x78\x15\x9b\x49\x5e", .priv_b = "\x63\x97\x6d\x4a\xae\x6c\xd0\xf6\xdd\x18\xde\xfe\xf5\x5d\x96\x56" @@ -38,8 +38,8 @@ dh_test_vector_t ecp224bp = { "\xdc\xcb\xe3\xb6\x5d\x0f\x96\x7d\xca\xb5\x74\xeb", }; -dh_test_vector_t ecp256bp = { - .group = ECP_256_BP, .priv_len = 32, .pub_len = 64, .shared_len = 32, +ke_test_vector_t ecp256bp = { + .method = ECP_256_BP, .priv_len = 32, .pub_len = 64, .shared_len = 32, .priv_a = "\x81\xdb\x1e\xe1\x00\x15\x0f\xf2\xea\x33\x8d\x70\x82\x71\xbe\x38" "\x30\x0c\xb5\x42\x41\xd7\x99\x50\xf7\x7b\x06\x30\x39\x80\x4f\x1d", .priv_b = "\x55\xe4\x0b\xc4\x1e\x37\xe3\xe2\xad\x25\xc3\xc6\x65\x45\x11\xff" @@ -56,8 +56,8 @@ dh_test_vector_t ecp256bp = { "\xf9\x65\x56\xec\x91\xe6\xae\x79\x39\xbc\xe3\x1f\x3a\x18\xbf\x2b", }; -dh_test_vector_t ecp384bp = { - .group = ECP_384_BP, .priv_len = 48, .pub_len = 96, .shared_len = 48, +ke_test_vector_t ecp384bp = { + .method = ECP_384_BP, .priv_len = 48, .pub_len = 96, .shared_len = 48, .priv_a = "\x1e\x20\xf5\xe0\x48\xa5\x88\x6f\x1f\x15\x7c\x74\xe9\x1b\xde\x2b" "\x98\xc8\xb5\x2d\x58\xe5\x00\x3d\x57\x05\x3f\xc4\xb0\xbd\x65\xd6" "\xf1\x5e\xb5\xd1\xee\x16\x10\xdf\x87\x07\x95\x14\x36\x27\xd0\x42", @@ -81,8 +81,8 @@ dh_test_vector_t ecp384bp = { "\xad\xf6\x40\x37\x15\xc3\x5d\x4f\xb2\xa5\x44\x4f\x57\x5d\x4f\x42", }; -dh_test_vector_t ecp512bp = { - .group = ECP_512_BP, .priv_len = 64, .pub_len = 128, .shared_len = 64, +ke_test_vector_t ecp512bp = { + .method = ECP_512_BP, .priv_len = 64, .pub_len = 128, .shared_len = 64, .priv_a = "\x16\x30\x2f\xf0\xdb\xbb\x5a\x8d\x73\x3d\xab\x71\x41\xc1\xb4\x5a" "\xcb\xc8\x71\x59\x39\x67\x7f\x6a\x56\x85\x0a\x38\xbd\x87\xbd\x59" "\xb0\x9e\x80\x27\x96\x09\xff\x33\x3e\xb9\xd4\xc0\x61\x23\x1f\xb2" diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/modp.c b/src/libstrongswan/plugins/test_vectors/test_vectors/modp.c index 2ef262493..897f537b7 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/modp.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/modp.c @@ -21,8 +21,8 @@ * these have been generated. */ -dh_test_vector_t modp768 = { - .group = MODP_768_BIT, .priv_len = 32, .pub_len = 96, .shared_len = 96, +ke_test_vector_t modp768 = { + .method = MODP_768_BIT, .priv_len = 32, .pub_len = 96, .shared_len = 96, .priv_a = "\x60\x91\xff\xc6\xde\x28\xc1\xcc\xc7\xc6\x5d\xa6\x11\xab\xfa\xe8" "\x6a\x10\x74\xb2\x22\x43\xe3\x70\x6c\xb6\xde\x2f\xe2\x9d\x11\x42", .priv_b = "\x76\xe0\x2f\xc3\xea\xbe\x6a\x0f\xce\xd6\xc3\x1e\x59\x45\xd1\x67" @@ -47,8 +47,8 @@ dh_test_vector_t modp768 = { "\x3d\xaa\xad\x22\xe8\x68\xb7\xe2\x50\x02\x9d\x30\x7e\xe5\x41\x48", }; -dh_test_vector_t modp1024 = { - .group = MODP_1024_BIT, .priv_len = 32, .pub_len = 128, .shared_len = 128, +ke_test_vector_t modp1024 = { + .method = MODP_1024_BIT, .priv_len = 32, .pub_len = 128, .shared_len = 128, .priv_a = "\xe5\x3c\x20\x5d\xa0\xd8\xe4\xbf\xb4\x17\x49\x44\x32\x0f\xc6\xe4" "\xea\x66\xfe\x44\xe3\xc9\x31\xac\x5d\xa1\x45\x0a\xea\x47\xeb\xcf", .priv_b = "\x7f\x9a\xf7\x21\xeb\x7c\xd2\xa9\x00\xa3\x6e\x39\x9e\xbc\x5c\x65" @@ -79,8 +79,8 @@ dh_test_vector_t modp1024 = { "\x48\x02\xd7\x4a\x4f\x75\x3b\x29\x4a\x96\x50\x3f\x26\x05\xd3\xf1", }; -dh_test_vector_t modp1536 = { - .group = MODP_1536_BIT, .priv_len = 32, .pub_len = 192, .shared_len = 192, +ke_test_vector_t modp1536 = { + .method = MODP_1536_BIT, .priv_len = 32, .pub_len = 192, .shared_len = 192, .priv_a = "\x22\xd9\xdc\xc7\x30\x79\x93\x6a\x85\x8c\x07\xaa\x85\xed\x07\xb3" "\xd1\xe8\xb6\x70\xe7\xca\xaf\xa1\x92\x83\x76\x96\x07\x0f\xef\x29", .priv_b = "\x32\x34\x74\xde\x77\x88\xe0\x03\x6b\x30\x95\x49\x56\x0b\x00\x0d" @@ -123,8 +123,8 @@ dh_test_vector_t modp1536 = { "\x38\x1b\x1e\x5b\x7a\xa5\xd0\x9a\xb6\x6b\x74\x99\x7c\xba\xed\x20", }; -dh_test_vector_t modp2048 = { - .group = MODP_2048_BIT, .priv_len = 48, .pub_len = 256, .shared_len = 256, +ke_test_vector_t modp2048 = { + .method = MODP_2048_BIT, .priv_len = 48, .pub_len = 256, .shared_len = 256, .priv_a = "\xaf\x3b\xfd\x38\x62\xca\xa1\x17\x74\xce\x2b\x74\x84\x08\x07\xc1" "\xde\x5c\xd6\xa7\x61\x9b\xb3\xa0\xc7\xaf\x39\xee\xda\xa6\xeb\x89" "\xe2\xe9\xc1\x44\xb3\x62\x5b\x27\x31\x87\x9c\xb5\x8f\xa3\x76\x6d", @@ -181,8 +181,8 @@ dh_test_vector_t modp2048 = { "\xee\x9c\x12\x15\xdd\x23\x93\xde\x02\xf5\xc1\x76\x7f\x07\x0e\x28", }; -dh_test_vector_t modp3072 = { - .group = MODP_3072_BIT, .priv_len = 48, .pub_len = 384, .shared_len = 384, +ke_test_vector_t modp3072 = { + .method = MODP_3072_BIT, .priv_len = 48, .pub_len = 384, .shared_len = 384, .priv_a = "\x51\xf8\xaa\xb6\x63\x20\x1e\xb2\x86\xba\xd2\x99\x32\xb2\xe5\x8a" "\x92\x96\xbf\x2a\xa7\x78\x79\xcc\x8c\x64\x29\xd5\xa6\x68\xad\xf7" "\x60\x57\xad\xc3\x77\xcc\x75\xfd\x86\x47\x96\xb8\xfa\x7b\x42\x8c", @@ -263,8 +263,8 @@ dh_test_vector_t modp3072 = { "\xdc\x87\x87\x5b\xe5\x88\xc0\xcd\xee\xee\xfd\x19\xcc\x4f\x1d\x40", }; -dh_test_vector_t modp4096 = { - .group = MODP_4096_BIT, .priv_len = 64, .pub_len = 512, .shared_len = 512, +ke_test_vector_t modp4096 = { + .method = MODP_4096_BIT, .priv_len = 64, .pub_len = 512, .shared_len = 512, .priv_a = "\xab\x69\xbc\xe9\x61\xf9\x8a\xa9\xd5\x91\xe3\xfd\x9a\xbc\x46\xc8" "\x0d\xde\x39\x02\x84\xf1\x91\x42\xe8\x81\x5a\xb0\x80\x54\x72\x2b" "\xbd\x2e\x14\x1e\x27\x9e\xc7\xfd\x30\xaa\xfa\xca\x66\x40\x93\x73" @@ -371,8 +371,8 @@ dh_test_vector_t modp4096 = { "\x4f\xb9\x39\x02\x12\xb9\xb2\xa3\x5d\x4a\xfa\x17\xb3\xee\xc0\x8a", }; -dh_test_vector_t modp6144 = { - .group = MODP_6144_BIT, .priv_len = 64, .pub_len = 768, .shared_len = 768, +ke_test_vector_t modp6144 = { + .method = MODP_6144_BIT, .priv_len = 64, .pub_len = 768, .shared_len = 768, .priv_a = "\xab\x36\xf0\x65\x7c\x4f\xba\xdc\x2a\x3b\x07\xed\xd1\xc8\xaf\xcb" "\x42\xaf\xcd\x7f\xf9\x1c\x57\x01\x37\x25\x50\x0d\x89\x42\x9f\x34" "\x79\x8f\x99\xf5\xde\x53\xd1\x08\x8f\xd9\xf6\x60\xa1\xa5\x2b\xe4" @@ -527,8 +527,8 @@ dh_test_vector_t modp6144 = { "\xb8\xd0\xeb\x41\xb6\x7c\xfb\x9d\x9d\xfd\x62\x0e\xb7\x99\xca\x17", }; -dh_test_vector_t modp8192 = { - .group = MODP_8192_BIT, .priv_len = 64, .pub_len = 1024, .shared_len = 1024, +ke_test_vector_t modp8192 = { + .method = MODP_8192_BIT, .priv_len = 64, .pub_len = 1024, .shared_len = 1024, .priv_a = "\xa6\x48\x81\x47\x45\xfe\x1e\xd1\x98\x9b\x75\xba\x6d\xd5\x01\xe4" "\x4e\x77\x6d\xc9\x97\xa0\xae\x27\x37\x64\x61\xb0\xee\x79\x65\x94" "\xc2\xe6\xdb\x07\xe5\xf9\xd8\x7d\x94\x4d\x37\x01\x22\x38\xe5\x70" diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/modpsub.c b/src/libstrongswan/plugins/test_vectors/test_vectors/modpsub.c index 4ccf20ae3..54b743e4b 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors/modpsub.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/modpsub.c @@ -20,8 +20,8 @@ * Test vectors from RFC5114 */ -dh_test_vector_t modp1024_160 = { - .group = MODP_1024_160, .priv_len = 20, .pub_len = 128, .shared_len = 128, +ke_test_vector_t modp1024_160 = { + .method = MODP_1024_160, .priv_len = 20, .pub_len = 128, .shared_len = 128, .priv_a = "\xB9\xA3\xB3\xAE\x8F\xEF\xC1\xA2\x93\x04\x96\x50\x70\x86\xF8\x45" "\x5D\x48\x94\x3E", .priv_b = "\x93\x92\xC9\xF9\xEB\x6A\x7A\x6A\x90\x22\xF7\xD8\x3E\x72\x23\xC6" @@ -52,8 +52,8 @@ dh_test_vector_t modp1024_160 = { "\x16\x7E\xCD\x91\x55\x41\x6F\x46\xF4\x08\xED\x31\xB6\x3C\x6E\x6D", }; -dh_test_vector_t modp2048_224 = { - .group = MODP_2048_224, .priv_len = 28, .pub_len = 256, .shared_len = 256, +ke_test_vector_t modp2048_224 = { + .method = MODP_2048_224, .priv_len = 28, .pub_len = 256, .shared_len = 256, .priv_a = "\x22\xe6\x26\x01\xdb\xff\xd0\x67\x08\xa6\x80\xf7\x47\xf3\x61\xf7" "\x6d\x8f\x4f\x72\x1a\x05\x48\xe4\x83\x29\x4b\x0c", .priv_b = "\x4f\xf3\xbc\x96\xc7\xfc\x6a\x6d\x71\xd3\xb3\x63\x80\x0a\x7c\xdf" @@ -108,8 +108,8 @@ dh_test_vector_t modp2048_224 = { "\x7f\xcb\x51\x0b\x69\x98\xff\xd3\xaa\x6d\xe7\x3c\xf9\xf6\x38\x69", }; -dh_test_vector_t modp2048_256 = { - .group = MODP_2048_256, .priv_len = 32, .pub_len = 256, .shared_len = 256, +ke_test_vector_t modp2048_256 = { + .method = MODP_2048_256, .priv_len = 32, .pub_len = 256, .shared_len = 256, .priv_a = "\x08\x81\x38\x2c\xdb\x87\x66\x0c\x6d\xc1\x3e\x61\x49\x38\xd5\xb9" "\xc8\xb2\xf2\x48\x58\x1c\xc5\xe3\x1b\x35\x45\x43\x97\xfc\xe5\x0e", .priv_b = "\x7d\x62\xa7\xe3\xef\x36\xde\x61\x7b\x13\xd1\xaf\xb8\x2c\x78\x0d" diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c index 86e4bc6cd..6c09271bd 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c @@ -29,7 +29,7 @@ #define TEST_VECTOR_KDF(x) extern kdf_test_vector_t x; #define TEST_VECTOR_DRBG(x) extern drbg_test_vector_t x; #define TEST_VECTOR_RNG(x) extern rng_test_vector_t x; -#define TEST_VECTOR_DH(x) extern dh_test_vector_t x; +#define TEST_VECTOR_KE(x) extern ke_test_vector_t x; #include "test_vectors.h" @@ -42,7 +42,7 @@ #undef TEST_VECTOR_KDF #undef TEST_VECTOR_DRBG #undef TEST_VECTOR_RNG -#undef TEST_VECTOR_DH +#undef TEST_VECTOR_KE #define TEST_VECTOR_CRYPTER(x) #define TEST_VECTOR_AEAD(x) @@ -53,7 +53,7 @@ #define TEST_VECTOR_KDF(x) #define TEST_VECTOR_DRBG(x) #define TEST_VECTOR_RNG(x) -#define TEST_VECTOR_DH(x) +#define TEST_VECTOR_KE(x) /* create test vector arrays */ #undef TEST_VECTOR_CRYPTER @@ -128,13 +128,13 @@ static rng_test_vector_t *rng[] = { #undef TEST_VECTOR_RNG #define TEST_VECTOR_RNG(x) -#undef TEST_VECTOR_DH -#define TEST_VECTOR_DH(x) &x, -static dh_test_vector_t *dh[] = { +#undef TEST_VECTOR_KE +#define TEST_VECTOR_KE(x) &x, +static ke_test_vector_t *ke[] = { #include "test_vectors.h" }; -#undef TEST_VECTOR_DH -#define TEST_VECTOR_DH(x) +#undef TEST_VECTOR_KE +#define TEST_VECTOR_KE(x) typedef struct private_test_vectors_plugin_t private_test_vectors_plugin_t; @@ -235,10 +235,10 @@ plugin_t *test_vectors_plugin_create() lib->crypto->add_test_vector(lib->crypto, RANDOM_NUMBER_GENERATOR, rng[i]); } - for (i = 0; i < countof(dh); i++) + for (i = 0; i < countof(ke); i++) { lib->crypto->add_test_vector(lib->crypto, - DIFFIE_HELLMAN_GROUP, dh[i]); + KEY_EXCHANGE_METHOD, ke[i]); } return &this->public.plugin; diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c index 6fefe523d..2f64c4800 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.c @@ -44,12 +44,12 @@ struct private_wolfssl_diffie_hellman_t { wolfssl_diffie_hellman_t public; /** - * Diffie Hellman group number. + * Diffie-Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** - * Diffie Hellman object + * Diffie-Hellman object */ DhKey dh; @@ -68,54 +68,63 @@ struct private_wolfssl_diffie_hellman_t { */ chunk_t pub; + /** + * Public key provided by peer + */ + chunk_t other; + /** * Shared secret */ chunk_t shared_secret; }; -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_wolfssl_diffie_hellman_t *this, chunk_t *value) { *value = chunk_copy_pad(chunk_alloc(this->len), this->pub, 0x00); return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +METHOD(key_exchange_t, get_shared_secret, bool, private_wolfssl_diffie_hellman_t *this, chunk_t *secret) { + word32 len; + if (!this->shared_secret.len) { - return FALSE; + this->shared_secret = chunk_alloc(this->len); + if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr, + this->priv.len, this->other.ptr, this->other.len) != 0) + { + DBG1(DBG_LIB, "DH shared secret computation failed"); + chunk_free(&this->shared_secret); + return FALSE; + } + this->shared_secret.len = len; } *secret = chunk_copy_pad(chunk_alloc(this->len), this->shared_secret, 0x00); return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_wolfssl_diffie_hellman_t *this, chunk_t value) { - word32 len; - - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } - - chunk_clear(&this->shared_secret); - this->shared_secret = chunk_alloc(this->len); - if (wc_DhAgree(&this->dh, this->shared_secret.ptr, &len, this->priv.ptr, - this->priv.len, value.ptr, value.len) != 0) + if (wc_DhCheckPubKey(&this->dh, value.ptr, value.len) != 0) { - DBG1(DBG_LIB, "DH shared secret computation failed"); - chunk_free(&this->shared_secret); + DBG1(DBG_LIB, "DH public key value invalid"); return FALSE; } - this->shared_secret.len = len; + chunk_clear(&this->other); + this->other = chunk_clone(value); return TRUE; } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_wolfssl_diffie_hellman_t *this, chunk_t value) { bool success = FALSE; @@ -141,18 +150,19 @@ METHOD(diffie_hellman_t, set_private_value, bool, return success; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_wolfssl_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_wolfssl_diffie_hellman_t *this) { wc_FreeDhKey(&this->dh); chunk_clear(&this->pub); chunk_clear(&this->priv); + chunk_clear(&this->other); chunk_clear(&this->shared_secret); free(this); } @@ -200,7 +210,7 @@ static int wolfssl_priv_key_size(int len) /** * Generic internal constructor */ -static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group, +static wolfssl_diffie_hellman_t *create_generic(key_exchange_method_t group, chunk_t g, chunk_t p) { private_wolfssl_diffie_hellman_t *this; @@ -209,12 +219,12 @@ static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group, INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, @@ -263,7 +273,7 @@ static wolfssl_diffie_hellman_t *create_generic(diffie_hellman_group_t group, * Described in header */ wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create( - diffie_hellman_group_t group, ...) + key_exchange_method_t group, ...) { diffie_hellman_params_t *params; chunk_t g, p; diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.h b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.h index 2f286ca42..4d5805613 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_diffie_hellman.h @@ -38,20 +38,20 @@ typedef struct wolfssl_diffie_hellman_t wolfssl_diffie_hellman_t; struct wolfssl_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new wolfssl_diffie_hellman_t object. * - * @param group Diffie Hellman group number to use + * @param group Diffie-Hellman group number to use * @param ... expects generator and prime as chunk_t if MODP_CUSTOM * @return wolfssl_diffie_hellman_t object, NULL if not supported */ wolfssl_diffie_hellman_t *wolfssl_diffie_hellman_create( - diffie_hellman_group_t group, ...); + key_exchange_method_t group, ...); #endif /** WOLFSSL_PLUGIN_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c index 4d3e8e21c..4ee286f71 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.c @@ -45,7 +45,7 @@ struct private_wolfssl_ec_diffie_hellman_t { /** * Diffie Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * EC curve id for creating keys @@ -62,29 +62,17 @@ struct private_wolfssl_ec_diffie_hellman_t { */ ecc_key key; + /** + * Public key provided by peer + */ + ecc_key pubkey; + /** * Shared secret */ chunk_t shared_secret; }; -/** - * Convert a chunk to an ecc_point (which must already exist). The x and y - * coordinates of the point have to be concatenated in the chunk. - */ -static bool chunk2ecp(chunk_t chunk, ecc_point *point) -{ - if (!wolfssl_mp_split(chunk, point->x, point->y)) - { - return FALSE; - } - if (mp_set(point->z, 1) != 0) - { - return FALSE; - } - return TRUE; -} - /** * Convert an ec_point to a chunk by concatenating the x and y coordinates of * the point. This function allocates memory for the chunk. @@ -138,79 +126,40 @@ static bool wolfssl_ecc_multiply(const ecc_set_type *ecc_set, mp_int *scalar, return ret == 0; } -/** - * Compute the shared secret. - * - * We cannot use the function wc_ecc_shared_secret() because that returns only - * the x coordinate of the shared secret point (which is defined, for instance, - * in 'NIST SP 800-56A'). - * However, we need both coordinates as RFC 4753 says: "The Diffie-Hellman - * public value is obtained by concatenating the x and y values. The format - * of the Diffie-Hellman shared secret value is the same as that of the - * Diffie-Hellman public value." - */ -static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this, - ecc_point *pub_key, chunk_t *shared_secret) -{ - ecc_point* secret; - bool success = FALSE; - - if ((secret = wc_ecc_new_point()) == NULL) - { - return FALSE; - } - - if (wolfssl_ecc_multiply(this->key.dp, &this->key.k, pub_key, secret)) - { - success = ecp2chunk(this->keysize, secret, shared_secret, TRUE); - } - - wc_ecc_del_point(secret); - return success; -} - -METHOD(diffie_hellman_t, set_other_public_value, bool, +METHOD(key_exchange_t, set_public_key, bool, private_wolfssl_ec_diffie_hellman_t *this, chunk_t value) { - ecc_point *pub_key; + chunk_t uncomp; - if (!diffie_hellman_verify_value(this->group, value)) + if (!key_exchange_verify_pubkey(this->group, value)) { return FALSE; } - if ((pub_key = wc_ecc_new_point()) == NULL) - { - return FALSE; - } - - if (!chunk2ecp(value, pub_key)) + /* prepend 0x04 to indicate uncompressed point format */ + uncomp = chunk_cata("cc", chunk_from_chars(0x04), value); + if (wc_ecc_import_x963_ex(uncomp.ptr, uncomp.len, &this->pubkey, + this->curve_id) != 0) { DBG1(DBG_LIB, "ECDH public value is malformed"); - wc_ecc_del_point(pub_key); return FALSE; } - chunk_clear(&this->shared_secret); - - if (!compute_shared_key(this, pub_key, &this->shared_secret)) + if (wc_ecc_check_key(&this->pubkey) != 0) { - DBG1(DBG_LIB, "ECDH shared secret computation failed"); - chunk_clear(&this->shared_secret); - wc_ecc_del_point(pub_key); + DBG1(DBG_LIB, "ECDH public value is invalid"); return FALSE; } - wc_ecc_del_point(pub_key); return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, bool, +METHOD(key_exchange_t, get_public_key, bool, private_wolfssl_ec_diffie_hellman_t *this,chunk_t *value) { return ecp2chunk(this->keysize, &this->key.pubkey, value, FALSE); } -METHOD(diffie_hellman_t, set_private_value, bool, +METHOD(key_exchange_t, set_private_key, bool, private_wolfssl_ec_diffie_hellman_t *this, chunk_t value) { bool success = FALSE; @@ -248,10 +197,51 @@ METHOD(diffie_hellman_t, set_private_value, bool, return success; } -METHOD(diffie_hellman_t, get_shared_secret, bool, +/** + * Derive the shared secret + */ +static bool compute_shared_key(private_wolfssl_ec_diffie_hellman_t *this) +{ + word32 len; +#ifdef ECC_TIMING_RESISTANT + WC_RNG rng; + + if (wc_InitRng(&rng) != 0) + { + return FALSE; + } + if (wc_ecc_set_rng(&this->key, &rng) != 0) + { + wc_FreeRng(&rng); + return FALSE; + } +#endif + + this->shared_secret = chunk_alloc(this->keysize); + len = this->shared_secret.len; + + if (wc_ecc_shared_secret(&this->key, &this->pubkey, this->shared_secret.ptr, + &len) != 0) + { + DBG1(DBG_LIB, "ECDH shared secret computation failed"); + chunk_clear(&this->shared_secret); +#ifdef ECC_TIMING_RESISTANT + wc_FreeRng(&rng); +#endif + return FALSE; + } + this->shared_secret.len = len; +#ifdef ECC_TIMING_RESISTANT + wc_FreeRng(&rng); +#endif + return TRUE; +} + +METHOD(key_exchange_t, get_shared_secret, bool, private_wolfssl_ec_diffie_hellman_t *this, chunk_t *secret) { - if (!this->shared_secret.len) + if (!this->shared_secret.len && + !compute_shared_key(this)) { return FALSE; } @@ -259,16 +249,17 @@ METHOD(diffie_hellman_t, get_shared_secret, bool, return TRUE; } -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_wolfssl_ec_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_wolfssl_ec_diffie_hellman_t *this) { wc_ecc_free(&this->key); + wc_ecc_free(&this->pubkey); chunk_clear(&this->shared_secret); free(this); } @@ -276,29 +267,29 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header */ -wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(diffie_hellman_group_t group) +wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create(key_exchange_method_t group) { private_wolfssl_ec_diffie_hellman_t *this; WC_RNG rng; INIT(this, .public = { - .dh = { + .ke = { .get_shared_secret = _get_shared_secret, - .set_other_public_value = _set_other_public_value, - .get_my_public_value = _get_my_public_value, - .set_private_value = _set_private_value, - .get_dh_group = _get_dh_group, + .set_public_key = _set_public_key, + .get_public_key = _get_public_key, + .set_private_key = _set_private_key, + .get_method = _get_method, .destroy = _destroy, }, }, .group = group, ); - if (wc_ecc_init(&this->key) != 0) + if (wc_ecc_init(&this->key) != 0 || wc_ecc_init(&this->pubkey) != 0) { DBG1(DBG_LIB, "key init failed, ecdh create failed"); - free(this); + destroy(this); return NULL; } diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h index d36f83f06..5864e22c8 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ec_diffie_hellman.h @@ -38,19 +38,19 @@ typedef struct wolfssl_ec_diffie_hellman_t wolfssl_ec_diffie_hellman_t; struct wolfssl_ec_diffie_hellman_t { /** - * Implements diffie_hellman_t interface. + * Implements key_exchange_t interface. */ - diffie_hellman_t dh; + key_exchange_t ke; }; /** * Creates a new wolfssl_ec_diffie_hellman_t object. * - * @param group EC Diffie Hellman group number to use + * @param group EC Diffie-Hellman group number to use * @return wolfssl_ec_diffie_hellman_t object, NULL if not * supported */ wolfssl_ec_diffie_hellman_t *wolfssl_ec_diffie_hellman_create( - diffie_hellman_group_t group); + key_exchange_method_t group); #endif /** WOLFSSL_PLUGIN_EC_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c index 6a13bf6fe..61c8e8e81 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c @@ -227,77 +227,77 @@ METHOD(plugin_t, get_features, int, #endif #ifdef HAVE_ECC_DHE /* EC DH groups */ - PLUGIN_REGISTER(DH, wolfssl_ec_diffie_hellman_create), + PLUGIN_REGISTER(KE, wolfssl_ec_diffie_hellman_create), #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 256) - PLUGIN_PROVIDE(DH, ECP_256_BIT), + PLUGIN_PROVIDE(KE, ECP_256_BIT), #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 384) - PLUGIN_PROVIDE(DH, ECP_384_BIT), + PLUGIN_PROVIDE(KE, ECP_384_BIT), #endif #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 521) - PLUGIN_PROVIDE(DH, ECP_521_BIT), + PLUGIN_PROVIDE(KE, ECP_521_BIT), #endif #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 224) - PLUGIN_PROVIDE(DH, ECP_224_BIT), + PLUGIN_PROVIDE(KE, ECP_224_BIT), #endif #if (defined(HAVE_ECC192) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 192) - PLUGIN_PROVIDE(DH, ECP_192_BIT), + PLUGIN_PROVIDE(KE, ECP_192_BIT), #endif #ifdef HAVE_ECC_BRAINPOOL #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 256) - PLUGIN_PROVIDE(DH, ECP_256_BP), + PLUGIN_PROVIDE(KE, ECP_256_BP), #endif #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 384) - PLUGIN_PROVIDE(DH, ECP_384_BP), + PLUGIN_PROVIDE(KE, ECP_384_BP), #endif #if (defined(HAVE_ECC512) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 512) - PLUGIN_PROVIDE(DH, ECP_512_BP), + PLUGIN_PROVIDE(KE, ECP_512_BP), #endif #if (defined(HAVE_ECC224) || defined(HAVE_ALL_CURVES)) && \ (!defined(ECC_MIN_KEY_SZ) || ECC_MIN_KEY_SZ <= 224) - PLUGIN_PROVIDE(DH, ECP_224_BP), + PLUGIN_PROVIDE(KE, ECP_224_BP), #endif #endif #endif /* HAVE_ECC_DHE */ #ifndef NO_DH /* MODP DH groups */ - PLUGIN_REGISTER(DH, wolfssl_diffie_hellman_create), + PLUGIN_REGISTER(KE, wolfssl_diffie_hellman_create), #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (3072 * 2) - PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_PROVIDE(KE, MODP_3072_BIT), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (4096 * 2) - PLUGIN_PROVIDE(DH, MODP_4096_BIT), + PLUGIN_PROVIDE(KE, MODP_4096_BIT), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (6144 * 2) - PLUGIN_PROVIDE(DH, MODP_6144_BIT), + PLUGIN_PROVIDE(KE, MODP_6144_BIT), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (8192 * 2) - PLUGIN_PROVIDE(DH, MODP_8192_BIT), + PLUGIN_PROVIDE(KE, MODP_8192_BIT), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (2048 * 2) - PLUGIN_PROVIDE(DH, MODP_2048_BIT), - PLUGIN_PROVIDE(DH, MODP_2048_224), - PLUGIN_PROVIDE(DH, MODP_2048_256), + PLUGIN_PROVIDE(KE, MODP_2048_BIT), + PLUGIN_PROVIDE(KE, MODP_2048_224), + PLUGIN_PROVIDE(KE, MODP_2048_256), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (1536 * 2) - PLUGIN_PROVIDE(DH, MODP_1536_BIT), + PLUGIN_PROVIDE(KE, MODP_1536_BIT), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (1024 * 2) - PLUGIN_PROVIDE(DH, MODP_1024_BIT), - PLUGIN_PROVIDE(DH, MODP_1024_160), + PLUGIN_PROVIDE(KE, MODP_1024_BIT), + PLUGIN_PROVIDE(KE, MODP_1024_160), #endif #if !defined(USE_FAST_MATH) || FP_MAX_BITS >= (768 * 2) - PLUGIN_PROVIDE(DH, MODP_768_BIT), + PLUGIN_PROVIDE(KE, MODP_768_BIT), #endif - PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_PROVIDE(KE, MODP_CUSTOM), #endif /* NO_DH */ #ifndef NO_RSA /* RSA private/public key loading */ @@ -439,12 +439,12 @@ METHOD(plugin_t, get_features, int, #endif /* HAVE_ECC_VERIFY */ #endif /* HAVE_ECC */ #if defined (HAVE_CURVE25519) || defined(HAVE_CURVE448) - PLUGIN_REGISTER(DH, wolfssl_x_diffie_hellman_create), + PLUGIN_REGISTER(KE, wolfssl_x_diffie_hellman_create), #ifdef HAVE_CURVE25519 - PLUGIN_PROVIDE(DH, CURVE_25519), + PLUGIN_PROVIDE(KE, CURVE_25519), #endif #ifdef HAVE_CURVE448 - PLUGIN_PROVIDE(DH, CURVE_448), + PLUGIN_PROVIDE(KE, CURVE_448), #endif #endif /* HAVE_CURVE25519 || HAVE_CURVE448 */ #if defined(HAVE_ED25519) || defined(HAVE_ED448) diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c index cbba467dc..f2361f2ef 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.c @@ -45,15 +45,16 @@ typedef struct private_diffie_hellman_t private_diffie_hellman_t; * Private data */ struct private_diffie_hellman_t { + /** * Public interface. */ - diffie_hellman_t public; + key_exchange_t public; /** * Diffie Hellman group number. */ - diffie_hellman_group_t group; + key_exchange_method_t group; /** * Private (public) key @@ -67,6 +68,18 @@ struct private_diffie_hellman_t { #endif } key; + /** + * Public key provided by peer + */ + union { +#ifdef HAVE_CURVE25519 + curve25519_key key25519; +#endif +#ifdef HAVE_CURVE448 + curve448_key key448; +#endif + } pub; + /** * Shared secret */ @@ -75,51 +88,46 @@ struct private_diffie_hellman_t { #ifdef HAVE_CURVE25519 -METHOD(diffie_hellman_t, set_other_public_value_25519, bool, - private_diffie_hellman_t *this, chunk_t value) +METHOD(key_exchange_t, get_shared_secret_25519, bool, + private_diffie_hellman_t *this, chunk_t *secret) { word32 len = CURVE25519_KEYSIZE; - curve25519_key pub; - int ret; - if (!diffie_hellman_verify_value(this->group, value)) + if (!this->shared_secret.len) { - return FALSE; - } - - ret = wc_curve25519_init(&pub); - if (ret != 0) - { - DBG1(DBG_LIB, "%N public key initialization failed", - diffie_hellman_group_names, this->group); - return FALSE; - } - - ret = wc_curve25519_import_public_ex(value.ptr, value.len, &pub, - EC25519_LITTLE_ENDIAN); - if (ret != 0) - { - DBG1(DBG_LIB, "%N public value is malformed", - diffie_hellman_group_names, this->group); - return FALSE; - } - - chunk_clear(&this->shared_secret); - this->shared_secret = chunk_alloc(len); - if (wc_curve25519_shared_secret_ex(&this->key.key25519, &pub, + this->shared_secret = chunk_alloc(len); + if (wc_curve25519_shared_secret_ex(&this->key.key25519, &this->pub.key25519, this->shared_secret.ptr, &len, EC25519_LITTLE_ENDIAN) != 0) - { - DBG1(DBG_LIB, "%N shared secret computation failed", - diffie_hellman_group_names, this->group); - chunk_clear(&this->shared_secret); - wc_curve25519_free(&pub); - return FALSE; + { + DBG1(DBG_LIB, "%N shared secret computation failed", + key_exchange_method_names, this->group); + chunk_clear(&this->shared_secret); + return FALSE; + } } - wc_curve25519_free(&pub); + *secret = chunk_clone(this->shared_secret); return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value_25519, bool, +METHOD(key_exchange_t, set_public_key_25519, bool, + private_diffie_hellman_t *this, chunk_t value) +{ + if (!key_exchange_verify_pubkey(this->group, value)) + { + return FALSE; + } + + if (wc_curve25519_import_public_ex(value.ptr, value.len, &this->pub.key25519, + EC25519_LITTLE_ENDIAN) != 0) + { + DBG1(DBG_LIB, "%N public value is malformed", + key_exchange_method_names, this->group); + return FALSE; + } + return TRUE; +} + +METHOD(key_exchange_t, get_public_key_25519, bool, private_diffie_hellman_t *this, chunk_t *value) { word32 len = CURVE25519_KEYSIZE; @@ -134,7 +142,7 @@ METHOD(diffie_hellman_t, get_my_public_value_25519, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value_25519, bool, +METHOD(key_exchange_t, set_private_key_25519, bool, private_diffie_hellman_t *this, chunk_t value) { curve25519_key pub; @@ -167,51 +175,46 @@ METHOD(diffie_hellman_t, set_private_value_25519, bool, #ifdef HAVE_CURVE448 -METHOD(diffie_hellman_t, set_other_public_value_448, bool, - private_diffie_hellman_t *this, chunk_t value) +METHOD(key_exchange_t, get_shared_secret_448, bool, + private_diffie_hellman_t *this, chunk_t *secret) { word32 len = CURVE448_KEY_SIZE; - curve448_key pub; - int ret; - if (!diffie_hellman_verify_value(this->group, value)) + if (!this->shared_secret.len) { - return FALSE; - } - - ret = wc_curve448_init(&pub); - if (ret != 0) - { - DBG1(DBG_LIB, "%N public key initialization failed", - diffie_hellman_group_names, this->group); - return FALSE; - } - - ret = wc_curve448_import_public_ex(value.ptr, value.len, &pub, - EC448_LITTLE_ENDIAN); - if (ret != 0) - { - DBG1(DBG_LIB, "%N public value is malformed", - diffie_hellman_group_names, this->group); - return FALSE; - } - - chunk_clear(&this->shared_secret); - this->shared_secret = chunk_alloc(len); - if (wc_curve448_shared_secret_ex(&this->key.key448, &pub, + this->shared_secret = chunk_alloc(len); + if (wc_curve448_shared_secret_ex(&this->key.key448, &this->pub.key448, this->shared_secret.ptr, &len, EC448_LITTLE_ENDIAN) != 0) - { - DBG1(DBG_LIB, "%N shared secret computation failed", - diffie_hellman_group_names, this->group); - chunk_clear(&this->shared_secret); - wc_curve448_free(&pub); - return FALSE; + { + DBG1(DBG_LIB, "%N shared secret computation failed", + key_exchange_method_names, this->group); + chunk_clear(&this->shared_secret); + return FALSE; + } } - wc_curve448_free(&pub); + *secret = chunk_clone(this->shared_secret); return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value_448, bool, +METHOD(key_exchange_t, set_public_key_448, bool, + private_diffie_hellman_t *this, chunk_t value) +{ + if (!key_exchange_verify_pubkey(this->group, value)) + { + return FALSE; + } + + if (wc_curve448_import_public_ex(value.ptr, value.len, &this->pub.key448, + EC448_LITTLE_ENDIAN) != 0) + { + DBG1(DBG_LIB, "%N public value is malformed", + key_exchange_method_names, this->group); + return FALSE; + } + return TRUE; +} + +METHOD(key_exchange_t, get_public_key_448, bool, private_diffie_hellman_t *this, chunk_t *value) { word32 len = CURVE448_KEY_SIZE; @@ -226,7 +229,7 @@ METHOD(diffie_hellman_t, get_my_public_value_448, bool, return TRUE; } -METHOD(diffie_hellman_t, set_private_value_448, bool, +METHOD(key_exchange_t, set_private_key_448, bool, private_diffie_hellman_t *this, chunk_t value) { curve448_key pub; @@ -257,36 +260,27 @@ METHOD(diffie_hellman_t, set_private_value_448, bool, #endif /* HAVE_CURVE448 */ -METHOD(diffie_hellman_t, get_shared_secret, bool, - private_diffie_hellman_t *this, chunk_t *secret) -{ - if (!this->shared_secret.len) - { - return FALSE; - } - *secret = chunk_clone(this->shared_secret); - return TRUE; -} - -METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, +METHOD(key_exchange_t, get_method, key_exchange_method_t, private_diffie_hellman_t *this) { return this->group; } -METHOD(diffie_hellman_t, destroy, void, +METHOD(key_exchange_t, destroy, void, private_diffie_hellman_t *this) { if (this->group == CURVE_25519) { #ifdef HAVE_CURVE25519 wc_curve25519_free(&this->key.key25519); + wc_curve25519_free(&this->pub.key25519); #endif } else if (this->group == CURVE_448) { #ifdef HAVE_CURVE448 wc_curve448_free(&this->key.key448); + wc_curve448_free(&this->pub.key448); #endif } chunk_clear(&this->shared_secret); @@ -296,7 +290,7 @@ METHOD(diffie_hellman_t, destroy, void, /* * Described in header */ -diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group) +key_exchange_t *wolfssl_x_diffie_hellman_create(key_exchange_method_t group) { private_diffie_hellman_t *this; WC_RNG rng; @@ -304,8 +298,7 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group) INIT(this, .public = { - .get_shared_secret = _get_shared_secret, - .get_dh_group = _get_dh_group, + .get_method = _get_method, .destroy = _destroy, }, .group = group, @@ -321,14 +314,16 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group) if (group == CURVE_25519) { #ifdef HAVE_CURVE25519 - this->public.set_other_public_value = _set_other_public_value_25519; - this->public.get_my_public_value = _get_my_public_value_25519; - this->public.set_private_value = _set_private_value_25519; + this->public.get_shared_secret = _get_shared_secret_25519; + this->public.set_public_key = _set_public_key_25519; + this->public.get_public_key = _get_public_key_25519; + this->public.set_private_key = _set_private_key_25519; - if (wc_curve25519_init(&this->key.key25519) != 0) + if (wc_curve25519_init(&this->key.key25519) != 0 || + wc_curve25519_init(&this->pub.key25519) != 0) { DBG1(DBG_LIB, "initializing key failed"); - free(this); + destroy(this); return NULL; } ret = wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, @@ -338,14 +333,16 @@ diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group) else if (group == CURVE_448) { #ifdef HAVE_CURVE448 - this->public.set_other_public_value = _set_other_public_value_448; - this->public.get_my_public_value = _get_my_public_value_448; - this->public.set_private_value = _set_private_value_448; + this->public.get_shared_secret = _get_shared_secret_448; + this->public.set_public_key = _set_public_key_448; + this->public.get_public_key = _get_public_key_448; + this->public.set_private_key = _set_private_key_448; - if (wc_curve448_init(&this->key.key448) != 0) + if (wc_curve448_init(&this->key.key448) != 0 || + wc_curve448_init(&this->pub.key448) != 0) { DBG1(DBG_LIB, "initializing key failed"); - free(this); + destroy(this); return NULL; } ret = wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &this->key.key448); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h index 91b3e19f1..4169652de 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_x_diffie_hellman.h @@ -33,11 +33,11 @@ #include /** - * Creates a new diffie_hellman_t object. + * Creates a new key_exchange_t object. * - * @param group Diffie Hellman group number to use + * @param group Diffie-Hellman group number to use * @return object, NULL if not supported */ -diffie_hellman_t *wolfssl_x_diffie_hellman_create(diffie_hellman_group_t group); +key_exchange_t *wolfssl_x_diffie_hellman_create(key_exchange_method_t group); #endif /** WOLFSSL_PLUGIN_X_DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/tests/suites/test_crypto_factory.c b/src/libstrongswan/tests/suites/test_crypto_factory.c index 0e965e2ac..48db5d811 100644 --- a/src/libstrongswan/tests/suites/test_crypto_factory.c +++ b/src/libstrongswan/tests/suites/test_crypto_factory.c @@ -141,93 +141,93 @@ START_TEST(test_create_rng) } END_TEST -static diffie_hellman_t *dh_create(char *plugin) +static key_exchange_t *ke_create(char *plugin) { - return (diffie_hellman_t*)plugin; + return (key_exchange_t*)plugin; } -static diffie_hellman_t *dh_create_modp1024(diffie_hellman_group_t group, ...) +static key_exchange_t *ke_create_modp1024(key_exchange_method_t group, ...) { ck_assert(group == MODP_1024_BIT); - return dh_create("plugin1"); + return ke_create("plugin1"); } -static diffie_hellman_t *dh_create_modp1024_second(diffie_hellman_group_t group, - ...) +static key_exchange_t *ke_create_modp1024_second(key_exchange_method_t group, + ...) { ck_assert(group == MODP_1024_BIT); - return dh_create("plugin2"); + return ke_create("plugin2"); } -static diffie_hellman_t *dh_create_modp2048(diffie_hellman_group_t group, ...) +static key_exchange_t *ke_create_modp2048(key_exchange_method_t group, ...) { ck_assert(group == MODP_2048_BIT); - return dh_create("plugin1"); + return ke_create("plugin1"); } -static diffie_hellman_t *dh_create_modp2048_second(diffie_hellman_group_t group, - ...) +static key_exchange_t *ke_create_modp2048_second(key_exchange_method_t group, + ...) { ck_assert(group == MODP_2048_BIT); - return dh_create("plugin2"); + return ke_create("plugin2"); } static struct { char *exp1024; char *exp2048; struct { - diffie_hellman_group_t g; - dh_constructor_t create; + key_exchange_method_t ke; + ke_constructor_t create; char *plugin; } data[4]; -} dh_data[] = { +} ke_data[] = { { NULL, NULL, { - { MODP_NONE, NULL, NULL } + { KE_NONE, NULL, NULL } }}, { "plugin1", NULL, { - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_NONE, NULL, NULL } + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { KE_NONE, NULL, NULL } }}, { "plugin1", NULL, { - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_1024_BIT, dh_create_modp1024_second, "plugin2" }, - { MODP_NONE, NULL, NULL } + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { MODP_1024_BIT, ke_create_modp1024_second, "plugin2" }, + { KE_NONE, NULL, NULL } }}, { "plugin2", NULL, { - { MODP_1024_BIT, dh_create_modp1024_second, "plugin2" }, - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_NONE, NULL, NULL } + { MODP_1024_BIT, ke_create_modp1024_second, "plugin2" }, + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { KE_NONE, NULL, NULL } }}, { "plugin1", "plugin1", { - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_2048_BIT, dh_create_modp2048, "plugin1" }, - { MODP_NONE, NULL } + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { MODP_2048_BIT, ke_create_modp2048, "plugin1" }, + { KE_NONE, NULL } }}, { "plugin1", "plugin1", { - { MODP_2048_BIT, dh_create_modp2048, "plugin1" }, - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_NONE, NULL } + { MODP_2048_BIT, ke_create_modp2048, "plugin1" }, + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { KE_NONE, NULL } }}, { "plugin1", "plugin1", { - { MODP_2048_BIT, dh_create_modp2048, "plugin1" }, - { MODP_2048_BIT, dh_create_modp2048_second, "plugin2" }, - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_NONE, NULL } + { MODP_2048_BIT, ke_create_modp2048, "plugin1" }, + { MODP_2048_BIT, ke_create_modp2048_second, "plugin2" }, + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { KE_NONE, NULL } }}, { "plugin1", "plugin2", { - { MODP_2048_BIT, dh_create_modp2048_second, "plugin2" }, - { MODP_2048_BIT, dh_create_modp2048, "plugin1" }, - { MODP_1024_BIT, dh_create_modp1024, "plugin1" }, - { MODP_NONE, NULL } + { MODP_2048_BIT, ke_create_modp2048_second, "plugin2" }, + { MODP_2048_BIT, ke_create_modp2048, "plugin1" }, + { MODP_1024_BIT, ke_create_modp1024, "plugin1" }, + { KE_NONE, NULL } }}, }; -static void verify_dh(crypto_factory_t *factory, diffie_hellman_group_t request, +static void verify_ke(crypto_factory_t *factory, key_exchange_method_t request, char *expected) { char *plugin; - plugin = (char*)factory->create_dh(factory, request); + plugin = (char*)factory->create_ke(factory, request); if (!expected) { ck_assert(!plugin); @@ -239,56 +239,56 @@ static void verify_dh(crypto_factory_t *factory, diffie_hellman_group_t request, } } -START_TEST(test_create_dh) +START_TEST(test_create_ke) { enumerator_t *enumerator; crypto_factory_t *factory; - diffie_hellman_group_t group; + key_exchange_method_t ke; char *plugin; int i, len = 0; factory = crypto_factory_create(); - for (i = 0; dh_data[_i].data[i].g != MODP_NONE; i++) + for (i = 0; ke_data[_i].data[i].ke != KE_NONE; i++) { - ck_assert(factory->add_dh(factory, dh_data[_i].data[i].g, - dh_data[_i].data[i].plugin, - dh_data[_i].data[i].create)); + ck_assert(factory->add_ke(factory, ke_data[_i].data[i].ke, + ke_data[_i].data[i].plugin, + ke_data[_i].data[i].create)); } - verify_dh(factory, MODP_1024_BIT, dh_data[_i].exp1024); - verify_dh(factory, MODP_2048_BIT, dh_data[_i].exp2048); + verify_ke(factory, MODP_1024_BIT, ke_data[_i].exp1024); + verify_ke(factory, MODP_2048_BIT, ke_data[_i].exp2048); - len = countof(dh_data[_i].data); - enumerator = factory->create_dh_enumerator(factory); - for (i = 0; enumerator->enumerate(enumerator, &group, &plugin) && i < len;) + len = countof(ke_data[_i].data); + enumerator = factory->create_ke_enumerator(factory); + for (i = 0; enumerator->enumerate(enumerator, &ke, &plugin) && i < len;) { - ck_assert_int_eq(dh_data[_i].data[i].g, group); - while (dh_data[_i].data[i].g == group) - { /* skip other entries by the same group */ + ck_assert_int_eq(ke_data[_i].data[i].ke, ke); + while (ke_data[_i].data[i].ke == ke) + { /* skip other entries of the same method */ i++; } - switch (group) + switch (ke) { case MODP_1024_BIT: - ck_assert(dh_data[_i].exp1024); - ck_assert_str_eq(dh_data[_i].exp1024, plugin); + ck_assert(ke_data[_i].exp1024); + ck_assert_str_eq(ke_data[_i].exp1024, plugin); break; case MODP_2048_BIT: - ck_assert(dh_data[_i].exp2048); - ck_assert_str_eq(dh_data[_i].exp2048, plugin); + ck_assert(ke_data[_i].exp2048); + ck_assert_str_eq(ke_data[_i].exp2048, plugin); break; default: - fail("unexpected DH group"); + fail("unexpected key exchange method"); break; } } ck_assert(!enumerator->enumerate(enumerator)); - ck_assert_int_eq(dh_data[_i].data[i].g, MODP_NONE); + ck_assert_int_eq(ke_data[_i].data[i].ke, KE_NONE); enumerator->destroy(enumerator); - for (i = 0; dh_data[_i].data[i].g != MODP_NONE; i++) + for (i = 0; ke_data[_i].data[i].ke != KE_NONE; i++) { - factory->remove_dh(factory, dh_data[_i].data[i].create); + factory->remove_ke(factory, ke_data[_i].data[i].create); } factory->destroy(factory); } @@ -305,8 +305,8 @@ Suite *crypto_factory_suite_create() tcase_add_loop_test(tc, test_create_rng, 0, countof(rng_data)); suite_add_tcase(s, tc); - tc = tcase_create("create_dh"); - tcase_add_loop_test(tc, test_create_dh, 0, countof(dh_data)); + tc = tcase_create("create_ke"); + tcase_add_loop_test(tc, test_create_ke, 0, countof(ke_data)); suite_add_tcase(s, tc); return s; diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c index a635f7ece..0a9f42bf9 100644 --- a/src/libstrongswan/tests/suites/test_ntru.c +++ b/src/libstrongswan/tests/suites/test_ntru.c @@ -54,8 +54,8 @@ IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data, ntru_public_ke * NTRU parameter sets to test */ static struct { - diffie_hellman_group_t group; - char *group_name; + key_exchange_method_t ke; + char *name; } params[] = { { NTRU_112_BIT, "NTRU_112" }, { NTRU_128_BIT, "NTRU_128" }, @@ -811,39 +811,39 @@ END_TEST START_TEST(test_ntru_ke) { chunk_t pub_key, cipher_text, i_shared_secret, r_shared_secret; - diffie_hellman_t *i_ntru, *r_ntru; + key_exchange_t *i_ntru, *r_ntru; char buf[10]; int k, n, len; k = (_i) / countof(parameter_sets); n = (_i) % countof(parameter_sets); - len = snprintf(buf, sizeof(buf), "%N", diffie_hellman_group_names, - params[k].group); + len = snprintf(buf, sizeof(buf), "%N", key_exchange_method_names, + params[k].ke); ck_assert(len == 8); - ck_assert(streq(buf, params[k].group_name)); + ck_assert(streq(buf, params[k].name)); lib->settings->set_str(lib->settings, "libstrongswan.plugins.ntru.parameter_set", parameter_sets[n]); - i_ntru = lib->crypto->create_dh(lib->crypto, params[k].group); + i_ntru = lib->crypto->create_ke(lib->crypto, params[k].ke); ck_assert(i_ntru != NULL); - ck_assert(i_ntru->get_dh_group(i_ntru) == params[k].group); + ck_assert(i_ntru->get_method(i_ntru) == params[k].ke); - ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); + ck_assert(i_ntru->get_public_key(i_ntru, &pub_key)); ck_assert(pub_key.len > 0); - r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group); + r_ntru = lib->crypto->create_ke(lib->crypto, params[k].ke); ck_assert(r_ntru != NULL); - ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key)); - ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); + ck_assert(r_ntru->set_public_key(r_ntru, pub_key)); + ck_assert(r_ntru->get_public_key(r_ntru, &cipher_text)); ck_assert(cipher_text.len > 0); ck_assert(r_ntru->get_shared_secret(r_ntru, &r_shared_secret)); ck_assert(r_shared_secret.len > 0); - ck_assert(i_ntru->set_other_public_value(i_ntru, cipher_text)); + ck_assert(i_ntru->set_public_key(i_ntru, cipher_text)); ck_assert(i_ntru->get_shared_secret(i_ntru, &i_shared_secret)); ck_assert(chunk_equals(i_shared_secret, r_shared_secret)); @@ -858,12 +858,12 @@ END_TEST START_TEST(test_ntru_retransmission) { - diffie_hellman_t *i_ntru; + key_exchange_t *i_ntru; chunk_t pub_key1, pub_key2; - i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT); - ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key1)); - ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key2)); + i_ntru = lib->crypto->create_ke(lib->crypto, NTRU_256_BIT); + ck_assert(i_ntru->get_public_key(i_ntru, &pub_key1)); + ck_assert(i_ntru->get_public_key(i_ntru, &pub_key2)); ck_assert(chunk_equals(pub_key1, pub_key2)); chunk_free(&pub_key1); @@ -885,12 +885,12 @@ chunk_t oid_tests[] = { START_TEST(test_ntru_pubkey_oid) { - diffie_hellman_t *r_ntru; + key_exchange_t *r_ntru; chunk_t cipher_text; - r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - ck_assert(!r_ntru->set_other_public_value(r_ntru, oid_tests[_i])); - ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); + r_ntru = lib->crypto->create_ke(lib->crypto, NTRU_128_BIT); + ck_assert(!r_ntru->set_public_key(r_ntru, oid_tests[_i])); + ck_assert(r_ntru->get_public_key(r_ntru, &cipher_text)); ck_assert(cipher_text.len == 0); r_ntru->destroy(r_ntru); } @@ -898,21 +898,21 @@ END_TEST START_TEST(test_ntru_wrong_set) { - diffie_hellman_t *i_ntru, *r_ntru; + key_exchange_t *i_ntru, *r_ntru; chunk_t pub_key, cipher_text; lib->settings->set_str(lib->settings, "libstrongswan.plugins.ntru.parameter_set", "x9_98_bandwidth"); - i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT); - ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); + i_ntru = lib->crypto->create_ke(lib->crypto, NTRU_112_BIT); + ck_assert(i_ntru->get_public_key(i_ntru, &pub_key)); lib->settings->set_str(lib->settings, "libstrongswan.plugins.ntru.parameter_set", "optimum"); - r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT); - ck_assert(!r_ntru->set_other_public_value(r_ntru, pub_key)); - ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); + r_ntru = lib->crypto->create_ke(lib->crypto, NTRU_112_BIT); + ck_assert(!r_ntru->set_public_key(r_ntru, pub_key)); + ck_assert(r_ntru->get_public_key(r_ntru, &cipher_text)); ck_assert(cipher_text.len == 0); chunk_free(&pub_key); @@ -933,7 +933,7 @@ START_TEST(test_ntru_ciphertext) chunk_create(buf_ff, sizeof(buf_ff)), }; - diffie_hellman_t *i_ntru; + key_exchange_t *i_ntru; chunk_t pub_key, shared_secret; int i; @@ -942,9 +942,9 @@ START_TEST(test_ntru_ciphertext) for (i = 0; i < countof(test); i++) { - i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); - ck_assert(!i_ntru->set_other_public_value(i_ntru, test[i])); + i_ntru = lib->crypto->create_ke(lib->crypto, NTRU_128_BIT); + ck_assert(i_ntru->get_public_key(i_ntru, &pub_key)); + ck_assert(!i_ntru->set_public_key(i_ntru, test[i])); ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret)); ck_assert(shared_secret.len == 0); @@ -956,18 +956,18 @@ END_TEST START_TEST(test_ntru_wrong_ciphertext) { - diffie_hellman_t *i_ntru, *r_ntru, *m_ntru; + key_exchange_t *i_ntru, *r_ntru, *m_ntru; chunk_t pub_key_i, pub_key_m, cipher_text, shared_secret; - i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); + i_ntru = lib->crypto->create_ke(lib->crypto, NTRU_128_BIT); + r_ntru = lib->crypto->create_ke(lib->crypto, NTRU_128_BIT); + m_ntru = lib->crypto->create_ke(lib->crypto, NTRU_128_BIT); - ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key_i)); - ck_assert(m_ntru->get_my_public_value(m_ntru, &pub_key_m)); - ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key_m)); - ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); - ck_assert(!i_ntru->set_other_public_value(i_ntru, cipher_text)); + ck_assert(i_ntru->get_public_key(i_ntru, &pub_key_i)); + ck_assert(m_ntru->get_public_key(m_ntru, &pub_key_m)); + ck_assert(r_ntru->set_public_key(r_ntru, pub_key_m)); + ck_assert(r_ntru->get_public_key(r_ntru, &cipher_text)); + ck_assert(!i_ntru->set_public_key(i_ntru, cipher_text)); ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret)); ck_assert(shared_secret.len == 0); diff --git a/src/libstrongswan/tests/suites/test_proposal.c b/src/libstrongswan/tests/suites/test_proposal.c index db9416a3d..c42f9e4a6 100644 --- a/src/libstrongswan/tests/suites/test_proposal.c +++ b/src/libstrongswan/tests/suites/test_proposal.c @@ -20,24 +20,24 @@ START_TEST(test_dh_group_mapping) { - enum_name_t *e = diffie_hellman_group_names_short; - diffie_hellman_group_t group; + enum_name_t *e = key_exchange_method_names_short; + key_exchange_method_t ke; const proposal_token_t *token; char *name; do { - for (group = e->first; group <= e->last; group++) + for (ke = e->first; ke <= e->last; ke++) { - if (group == MODP_CUSTOM) + if (ke == MODP_CUSTOM) { /* can't be configured */ continue; } - name = e->names[group - e->first]; + name = e->names[ke - e->first]; token = lib->proposal->get_token(lib->proposal, name); ck_assert_msg(token, "%s can't be mapped", name); - ck_assert_int_eq(token->type, DIFFIE_HELLMAN_GROUP); - ck_assert_int_eq(token->algorithm, group); + ck_assert_int_eq(token->type, KEY_EXCHANGE_METHOD); + ck_assert_int_eq(token->algorithm, ke); } } while ((e = e->next)); @@ -55,7 +55,7 @@ static struct { { PROTO_IKE, "null-sha256-modp3072", "IKE:NULL/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072" }, { PROTO_IKE, "aes128", NULL }, { PROTO_IKE, "aes128-sha256", NULL }, - { PROTO_IKE, "aes128-sha256-modpnone", NULL }, + { PROTO_IKE, "aes128-sha256-none", NULL }, { PROTO_IKE, "aes128-prfsha256", NULL }, { PROTO_IKE, "aes128-prfsha256-modp2048", NULL }, { PROTO_IKE, "aes128-sha256-modp3072", "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072" }, @@ -124,25 +124,25 @@ static struct { { PROTO_ESP, "aes128-aes256-sha1-sha256", "aes256-aes128-sha256-sha1", "aes128-sha1" }, { PROTO_ESP, "aes256-aes128-sha256-sha1", "aes128-aes256-sha1-sha256", "aes256-sha256" }, { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256", NULL }, - { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256", "aes128-sha256", PROPOSAL_SKIP_DH }, + { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256", "aes128-sha256", PROPOSAL_SKIP_KE }, { PROTO_ESP, "aes128-sha256", "aes128-sha256-modp3072", NULL }, - { PROTO_ESP, "aes128-sha256", "aes128-sha256-modp3072", "aes128-sha256", PROPOSAL_SKIP_DH }, - { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-modp3072", "aes128-sha256", PROPOSAL_SKIP_DH }, - { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-ecp256", "aes128-sha256", PROPOSAL_SKIP_DH }, - { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-modpnone", NULL }, - { PROTO_ESP, "aes128-sha256-modpnone", "aes128-sha256-modp3072", NULL }, - { PROTO_ESP, "aes128-sha256-modp3072-modpnone", "aes128-sha256", "aes128-sha256" }, - { PROTO_ESP, "aes128-sha256", "aes128-sha256-modp3072-modpnone", "aes128-sha256" }, - { PROTO_ESP, "aes128-sha256-modp3072-modpnone", "aes128-sha256-modpnone-modp3072", "aes128-sha256-modp3072" }, - { PROTO_ESP, "aes128-sha256-modpnone-modp3072", "aes128-sha256-modp3072-modpnone", "aes128-sha256" }, + { PROTO_ESP, "aes128-sha256", "aes128-sha256-modp3072", "aes128-sha256", PROPOSAL_SKIP_KE }, + { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-modp3072", "aes128-sha256", PROPOSAL_SKIP_KE }, + { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-ecp256", "aes128-sha256", PROPOSAL_SKIP_KE }, + { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-none", NULL }, + { PROTO_ESP, "aes128-sha256-none", "aes128-sha256-modp3072", NULL }, + { PROTO_ESP, "aes128-sha256-modp3072-none", "aes128-sha256", "aes128-sha256" }, + { PROTO_ESP, "aes128-sha256", "aes128-sha256-modp3072-none", "aes128-sha256" }, + { PROTO_ESP, "aes128-sha256-modp3072-none", "aes128-sha256-none-modp3072", "aes128-sha256-modp3072" }, + { PROTO_ESP, "aes128-sha256-none-modp3072", "aes128-sha256-modp3072-none", "aes128-sha256" }, { PROTO_ESP, "aes128-sha256-esn", "aes128-sha256-esn", "aes128-sha256-esn" }, { PROTO_ESP, "aes128-sha256-noesn", "aes128-sha256-esn", NULL }, { PROTO_ESP, "aes128-sha256-noesn-esn", "aes128-sha256-esn", "aes128-sha256-esn" }, { PROTO_ESP, "aes128-sha256-noesn-esn", "aes128-sha256", "aes128-sha256" }, { PROTO_ESP, "aes128-sha256-esn-noesn", "aes128-sha256-noesn-esn", "aes128-sha256-esn" }, { PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072", "aes128-sha256-modp3072" }, - { PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072-modpnone", "aes128-sha256-modp3072" }, - { PROTO_IKE, "aes128-sha256-modp3072-modpnone", "aes128-sha256-modp3072", "aes128-sha256-modp3072" }, + { PROTO_IKE, "aes128-sha256-modp3072", "aes128-sha256-modp3072-none", "aes128-sha256-modp3072" }, + { PROTO_IKE, "aes128-sha256-modp3072-none", "aes128-sha256-modp3072", "aes128-sha256-modp3072" }, }; START_TEST(test_select) @@ -246,10 +246,10 @@ static struct { { "aes256-modp2048", "aes128-modp2048" }, NULL }, { PROTO_ESP, { "aes128-modp1024", "aes256-modp1024" }, { "aes256-modp2048", "aes128-modp2048" }, "aes128", - PROPOSAL_SKIP_DH }, + PROPOSAL_SKIP_KE }, { PROTO_ESP, { "aes128-modp1024", "aes256-modp1024" }, { "aes256-modp2048", "aes128-modp2048" }, "aes256", - PROPOSAL_PREFER_SUPPLIED | PROPOSAL_SKIP_DH }, + PROPOSAL_PREFER_SUPPLIED | PROPOSAL_SKIP_KE }, }; START_TEST(test_select_proposal) @@ -301,38 +301,89 @@ START_TEST(test_select_proposal) } END_TEST -START_TEST(test_promote_dh_group) +START_TEST(test_has_transform) { proposal_t *proposal; proposal = proposal_create_from_string(PROTO_IKE, "aes128-sha256-modp3072-ecp256"); - ck_assert(proposal->promote_dh_group(proposal, ECP_256_BIT)); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_3072_BIT)); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + ECP_256_BIT)); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_2048_BIT)); + proposal->destroy(proposal); +} +END_TEST + +START_TEST(test_has_transform_none) +{ + proposal_t *proposal; + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256"); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_NONE)); + proposal->destroy(proposal); + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-none"); + ck_assert(proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_NONE)); + proposal->destroy(proposal); + + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-modp3072"); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_NONE)); + proposal->destroy(proposal); + + /* while actually contained in the proposal, KE_NONE is 0 so we expect + * has_transform() to return FALSE if there are other algorithms */ + proposal = proposal_create_from_string(PROTO_ESP, + "aes128-sha256-modp3072-none"); + ck_assert(!proposal->has_transform(proposal, KEY_EXCHANGE_METHOD, + KE_NONE)); + proposal->destroy(proposal); +} +END_TEST + +START_TEST(test_promote_transform) +{ + proposal_t *proposal; + + proposal = proposal_create_from_string(PROTO_IKE, + "aes128-sha256-modp3072-ecp256"); + ck_assert(proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + ECP_256_BIT)); assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/ECP_256/MODP_3072"); proposal->destroy(proposal); } END_TEST -START_TEST(test_promote_dh_group_already_front) +START_TEST(test_promote_transform_already_front) { proposal_t *proposal; proposal = proposal_create_from_string(PROTO_IKE, "aes128-sha256-modp3072-ecp256"); - ck_assert(proposal->promote_dh_group(proposal, MODP_3072_BIT)); + ck_assert(proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_3072_BIT)); assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256"); proposal->destroy(proposal); } END_TEST -START_TEST(test_promote_dh_group_not_contained) +START_TEST(test_promote_transform_not_contained) { proposal_t *proposal; proposal = proposal_create_from_string(PROTO_IKE, "aes128-sha256-modp3072-ecp256"); - ck_assert(!proposal->promote_dh_group(proposal, MODP_2048_BIT)); + ck_assert(!proposal->promote_transform(proposal, KEY_EXCHANGE_METHOD, + MODP_2048_BIT)); assert_proposal_eq(proposal, "IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_3072/ECP_256"); proposal->destroy(proposal); } @@ -447,11 +498,11 @@ static struct { { PROTO_ESP, "aes128-serpent", "aes128-serpent" }, { PROTO_ESP, "aes128-serpent", "aes128", PROPOSAL_SKIP_PRIVATE }, { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256-modp3072" }, - { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256", PROPOSAL_SKIP_DH }, + { PROTO_ESP, "aes128-sha256-modp3072", "aes128-sha256", PROPOSAL_SKIP_KE }, { PROTO_ESP, "aes128-serpent-modp3072", "aes128-serpent", - PROPOSAL_SKIP_DH }, + PROPOSAL_SKIP_KE }, { PROTO_ESP, "aes128-serpent-modp3072", "aes128", - PROPOSAL_SKIP_PRIVATE | PROPOSAL_SKIP_DH }, + PROPOSAL_SKIP_PRIVATE | PROPOSAL_SKIP_KE }, }; START_TEST(test_clone) @@ -505,10 +556,15 @@ Suite *proposal_suite_create() countof(select_proposal_data)); suite_add_tcase(s, tc); - tc = tcase_create("promote_dh_group"); - tcase_add_test(tc, test_promote_dh_group); - tcase_add_test(tc, test_promote_dh_group_already_front); - tcase_add_test(tc, test_promote_dh_group_not_contained); + tc = tcase_create("has_transform"); + tcase_add_test(tc, test_has_transform); + tcase_add_test(tc, test_has_transform_none); + suite_add_tcase(s, tc); + + tc = tcase_create("promote_transform"); + tcase_add_test(tc, test_promote_transform); + tcase_add_test(tc, test_promote_transform_already_front); + tcase_add_test(tc, test_promote_transform_not_contained); suite_add_tcase(s, tc); tc = tcase_create("unknown transform types"); diff --git a/src/libstrongswan/tests/suites/test_vectors.c b/src/libstrongswan/tests/suites/test_vectors.c index bd619f3b1..212a315b4 100644 --- a/src/libstrongswan/tests/suites/test_vectors.c +++ b/src/libstrongswan/tests/suites/test_vectors.c @@ -31,7 +31,7 @@ static transform_type_t tfs[] = { KEY_DERIVATION_FUNCTION, DETERMINISTIC_RANDOM_BIT_GENERATOR, RANDOM_NUMBER_GENERATOR, - DIFFIE_HELLMAN_GROUP, + KEY_EXCHANGE_METHOD, }; START_TEST(test_vectors) diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index caaa4d226..6d83d83a8 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -735,6 +735,30 @@ static bool run_suite(test_suite_t *suite, test_runner_init_t init, char *cfg, return FALSE; } +/** + * Configure log levels for specific groups + */ +static void setup_log_levels(level_t *base) +{ + char buf[BUF_LEN], *verbosity; + debug_t group; + level_t level; + + for (group = 0; group < DBG_MAX; group++) + { + snprintf(buf, sizeof(buf), "TESTS_VERBOSITY_%s", + enum_to_name(debug_names, group)); + + verbosity = getenv(buf); + if (verbosity) + { + level = atoi(verbosity); + dbg_default_set_level_group(group, level); + *base = max(*base, level); + } + } +} + /** * See header. */ @@ -772,6 +796,8 @@ int test_runner_run(const char *name, test_configuration_t configs[], } dbg_default_set_level(level); + setup_log_levels(&level); + fprintf(stderr, "Running %u '%s' test suites:\n", array_count(suites), name); enumerator = array_create_enumerator(suites); diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h index 21c00b2b7..894830fe4 100644 --- a/src/libstrongswan/tests/tests.h +++ b/src/libstrongswan/tests/tests.h @@ -57,7 +57,7 @@ TEST_SUITE(rng_tester_suite_create) TEST_SUITE_DEPEND(mgf1_sha1_suite_create, XOF, XOF_MGF1_SHA1) TEST_SUITE_DEPEND(mgf1_sha256_suite_create, XOF, XOF_MGF1_SHA256) TEST_SUITE_DEPEND(prf_plus_suite_create, KDF, KDF_PRF_PLUS) -TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT) +TEST_SUITE_DEPEND(ntru_suite_create, KE, NTRU_112_BIT) TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://") TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519) TEST_SUITE_DEPEND(ed448_suite_create, PRIVKEY_GEN, KEY_ED448) diff --git a/src/libstrongswan/utils/debug.c b/src/libstrongswan/utils/debug.c index a3a042be5..a5d478421 100644 --- a/src/libstrongswan/utils/debug.c +++ b/src/libstrongswan/utils/debug.c @@ -63,9 +63,10 @@ ENUM(debug_lower_names, DBG_DMN, DBG_ANY, ); /** - * level logged by the default logger + * level logged by the default logger for specific groups, to simplify things + * we store level-1, so initialization to 0 is like setting it to 1 */ -static level_t default_level = 1; +static level_t default_level[DBG_MAX]; /** * stream logged to by the default logger @@ -81,7 +82,8 @@ void dbg_default(debug_t group, level_t level, char *fmt, ...) { default_stream = stderr; } - if (level <= default_level) + /* levels are stored as level-1 */ + if (level <= default_level[group]+1) { va_list args; @@ -92,16 +94,34 @@ void dbg_default(debug_t group, level_t level, char *fmt, ...) } } -/** - * set the level logged by the default stderr logger +/* + * Described in header + */ +void dbg_default_set_level_group(debug_t group, level_t level) +{ + if (group < DBG_ANY) + { + default_level[group] = level-1; + } + else + { + for (group = 0; group < DBG_MAX; group++) + { + default_level[group] = level-1; + } + } +} + +/* + * Described in header */ void dbg_default_set_level(level_t level) { - default_level = level; + dbg_default_set_level_group(DBG_ANY, level); } -/** - * set the stream logged by dbg_default() to +/* + * Described in header */ void dbg_default_set_stream(FILE *stream) { @@ -112,4 +132,3 @@ void dbg_default_set_stream(FILE *stream) * The registered debug hook. */ void (*dbg) (debug_t group, level_t level, char *fmt, ...) = dbg_default; - diff --git a/src/libstrongswan/utils/debug.h b/src/libstrongswan/utils/debug.h index 50ebbf50f..127da579a 100644 --- a/src/libstrongswan/utils/debug.h +++ b/src/libstrongswan/utils/debug.h @@ -146,9 +146,12 @@ extern void (*dbg) (debug_t group, level_t level, char *fmt, ...); /** default logging function */ void dbg_default(debug_t group, level_t level, char *fmt, ...); -/** set the level logged by dbg_default() */ +/** set the level logged by dbg_default() for all groups */ void dbg_default_set_level(level_t level); +/** set the level logged by dbg_default() for a specific group */ +void dbg_default_set_level_group(debug_t group, level_t level); + /** set the stream logged by dbg_default() to */ void dbg_default_set_stream(FILE *stream); diff --git a/src/libstrongswan/utils/utils/status.c b/src/libstrongswan/utils/utils/status.c index dd0778179..2aced5e41 100644 --- a/src/libstrongswan/utils/utils/status.c +++ b/src/libstrongswan/utils/utils/status.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2018 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -32,18 +32,26 @@ ENUM(status_names, SUCCESS, NEED_MORE, "NEED_MORE", ); -/** - * returns FAILED +/* + * Described in header */ status_t return_failed() { return FAILED; } -/** - * returns SUCCESS +/* + * Described in header */ status_t return_success() { return SUCCESS; } + +/* + * Described in header + */ +status_t return_need_more() +{ + return NEED_MORE; +} diff --git a/src/libstrongswan/utils/utils/status.h b/src/libstrongswan/utils/utils/status.h index 5f47e1f66..954b1043a 100644 --- a/src/libstrongswan/utils/utils/status.h +++ b/src/libstrongswan/utils/utils/status.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2014 Tobias Brunner + * Copyright (C) 2008-2018 Tobias Brunner * Copyright (C) 2008 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -70,4 +70,9 @@ status_t return_failed(); */ status_t return_success(); +/** + * returns NEED_MORE + */ +status_t return_need_more(); + #endif /** STATUS_H_ @} */ diff --git a/src/libtls/tests/suites/test_socket.c b/src/libtls/tests/suites/test_socket.c index a72c91ef7..2b1b5c89a 100644 --- a/src/libtls/tests/suites/test_socket.c +++ b/src/libtls/tests/suites/test_socket.c @@ -581,7 +581,7 @@ static void test_tls(tls_version_t version, uint16_t port, bool cauth, u_int i) static void test_tls_ke_groups(tls_version_t version, uint16_t port, bool cauth, u_int i) { - diffie_hellman_group_t *groups; + key_exchange_method_t *groups; char curve[128]; int count; @@ -591,7 +591,7 @@ static void test_tls_ke_groups(tls_version_t version, uint16_t port, bool cauth, count = tls_crypto_get_supported_groups(&groups); ck_assert(i < count); - snprintf(curve, sizeof(curve), "%N", diffie_hellman_group_names_short, + snprintf(curve, sizeof(curve), "%N", key_exchange_method_names_short, groups[i]); lib->settings->set_str(lib->settings, "%s.tls.ke_group", curve, lib->ns); diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index a1a24a7bb..cb0e003c9 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -481,7 +481,7 @@ struct private_tls_crypto_t { typedef struct { tls_cipher_suite_t suite; key_type_t key; - diffie_hellman_group_t dh; + key_exchange_method_t dh; hash_algorithm_t hash; pseudo_random_function_t prf; integrity_algorithm_t mac; @@ -508,33 +508,33 @@ typedef struct { */ static suite_algs_t suite_algs[] = { /* Cipher suites of TLS 1.3: key exchange and authentication - * delegated to extensions, therefore KEY_ANY, MODP_NONE, PRF_UNDEFINED */ + * delegated to extensions, therefore KEY_ANY, KE_NONE, PRF_UNDEFINED */ { TLS_AES_256_GCM_SHA384, - KEY_ANY, MODP_NONE, + KEY_ANY, KE_NONE, HASH_SHA384, PRF_UNDEFINED, AUTH_HMAC_SHA2_384_384, ENCR_AES_GCM_ICV16, 32, TLS_1_3, TLS_1_3, }, { TLS_AES_128_GCM_SHA256, - KEY_ANY, MODP_NONE, + KEY_ANY, KE_NONE, HASH_SHA256, PRF_UNDEFINED, AUTH_HMAC_SHA2_256_256, ENCR_AES_GCM_ICV16, 16, TLS_1_3, TLS_1_3, }, { TLS_CHACHA20_POLY1305_SHA256, - KEY_ANY, MODP_NONE, + KEY_ANY, KE_NONE, HASH_SHA256, PRF_UNDEFINED, AUTH_HMAC_SHA2_256_256, ENCR_CHACHA20_POLY1305, 32, TLS_1_3, TLS_1_3, }, { TLS_AES_128_CCM_SHA256, - KEY_ANY, MODP_NONE, + KEY_ANY, KE_NONE, HASH_SHA256, PRF_UNDEFINED, AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV16, 16, TLS_1_3, TLS_1_3, }, { TLS_AES_128_CCM_8_SHA256, - KEY_ANY, MODP_NONE, + KEY_ANY, KE_NONE, HASH_SHA256, PRF_UNDEFINED, AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV8, 16, TLS_1_3, TLS_1_3, @@ -673,61 +673,61 @@ static suite_algs_t suite_algs[] = { SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_AES_256_GCM_SHA384, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA384, PRF_HMAC_SHA2_384, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_256_CBC_SHA256, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_256_CBC_SHA, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_AES_128_GCM_SHA256, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_128_CBC_SHA256, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_AES_128_CBC_SHA, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32, SSL_3_0, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16, SSL_3_0, TLS_1_2, @@ -745,13 +745,13 @@ static suite_algs_t suite_algs[] = { TLS_1_0, TLS_1_2, }, { TLS_RSA_WITH_NULL_SHA256, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0, TLS_1_2, TLS_1_2, }, { TLS_RSA_WITH_NULL_SHA, - KEY_RSA, MODP_NONE, + KEY_RSA, KE_NONE, HASH_SHA256, PRF_HMAC_SHA2_256, AUTH_HMAC_SHA1_160, ENCR_NULL, 0, SSL_3_0, TLS_1_2, @@ -836,9 +836,9 @@ static void filter_suite(suite_algs_t suites[], int *count, int offset, } if (current.dh && current.dh != suites[i].dh) { - if (suites[i].dh != MODP_NONE && - !(diffie_hellman_group_is_ec(current.dh) && - diffie_hellman_group_is_ec(suites[i].dh))) + if (suites[i].dh != KE_NONE && + !(key_exchange_is_ecdh(current.dh) && + key_exchange_is_ecdh(suites[i].dh))) { /* skip DH group, does not match nor NONE nor both ECDH */ continue; } @@ -911,29 +911,29 @@ static void filter_key_exchange_config_suites(private_tls_crypto_t *this, while (enumerator->enumerate(enumerator, &token)) { if (strcaseeq(token, "ecdhe-ecdsa") && - diffie_hellman_group_is_ec(suites[i].dh) && + key_exchange_is_ecdh(suites[i].dh) && suites[i].key == KEY_ECDSA) { suites[remaining++] = suites[i]; break; } if (strcaseeq(token, "ecdhe-rsa") && - diffie_hellman_group_is_ec(suites[i].dh) && + key_exchange_is_ecdh(suites[i].dh) && suites[i].key == KEY_RSA) { suites[remaining++] = suites[i]; break; } if (strcaseeq(token, "dhe-rsa") && - !diffie_hellman_group_is_ec(suites[i].dh) && - suites[i].dh != MODP_NONE && + !key_exchange_is_ecdh(suites[i].dh) && + suites[i].dh != KE_NONE && suites[i].key == KEY_RSA) { suites[remaining++] = suites[i]; break; } if (strcaseeq(token, "rsa") && - suites[i].dh == MODP_NONE && + suites[i].dh == KE_NONE && suites[i].key == KEY_RSA) { suites[remaining++] = suites[i]; @@ -1076,7 +1076,7 @@ static bool filter_curve_config(tls_named_group_t curve) const proposal_token_t *tok; tok = lib->proposal->get_token(lib->proposal, token); - if (tok != NULL && tok->type == DIFFIE_HELLMAN_GROUP && + if (tok != NULL && tok->type == KEY_EXCHANGE_METHOD && curve == tls_ec_group_to_curve(tok->algorithm)) { enumerator->destroy(enumerator); @@ -1105,7 +1105,7 @@ static void filter_unsupported_suites(suite_algs_t suites[], int *count) filter_suite(suites, count, offsetof(suite_algs_t, hash), lib->crypto->create_hasher_enumerator); filter_suite(suites, count, offsetof(suite_algs_t, dh), - lib->crypto->create_dh_enumerator); + lib->crypto->create_ke_enumerator); } /** @@ -1526,7 +1526,7 @@ static signature_params_t *params_for_scheme(tls_signature_scheme_t sig, * Mapping groups to TLS named curves */ static struct { - diffie_hellman_group_t group; + key_exchange_method_t group; tls_named_group_t curve; } curves[] = { { ECP_256_BIT, TLS_SECP256R1}, @@ -1541,7 +1541,7 @@ static struct { CALLBACK(group_filter, bool, void *null, enumerator_t *orig, va_list args) { - diffie_hellman_group_t group, *group_out; + key_exchange_method_t group, *group_out; tls_named_group_t curve, *curve_out; char *plugin; @@ -1569,7 +1569,7 @@ CALLBACK(group_filter, bool, CALLBACK(config_filter, bool, void *null, enumerator_t *orig, va_list args) { - diffie_hellman_group_t group, *group_out; + key_exchange_method_t group, *group_out; tls_named_group_t curve, *curve_out; VA_ARGS_VGET(args, group_out, curve_out); @@ -1598,7 +1598,7 @@ METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*, { return enumerator_create_filter( enumerator_create_filter( - lib->crypto->create_dh_enumerator(lib->crypto), + lib->crypto->create_ke_enumerator(lib->crypto), group_filter, NULL, NULL), config_filter, NULL, NULL); } @@ -1607,10 +1607,10 @@ METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*, * Check if the given ECDH group is supported or return the first one we * actually do support. */ -static diffie_hellman_group_t supported_ec_group(private_tls_crypto_t *this, - diffie_hellman_group_t orig) +static key_exchange_method_t supported_ec_group(private_tls_crypto_t *this, + key_exchange_method_t orig) { - diffie_hellman_group_t current, first = MODP_NONE; + key_exchange_method_t current, first = KE_NONE; enumerator_t *enumerator; enumerator = create_ec_enumerator(this); @@ -1621,7 +1621,7 @@ static diffie_hellman_group_t supported_ec_group(private_tls_crypto_t *this, enumerator->destroy(enumerator); return orig; } - else if (first == MODP_NONE) + else if (first == KE_NONE) { first = current; } @@ -1630,7 +1630,7 @@ static diffie_hellman_group_t supported_ec_group(private_tls_crypto_t *this, return first; } -METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t, +METHOD(tls_crypto_t, get_dh_group, key_exchange_method_t, private_tls_crypto_t *this) { suite_algs_t *algs; @@ -1638,13 +1638,13 @@ METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t, algs = find_suite(this->suite); if (algs) { - if (diffie_hellman_group_is_ec(algs->dh)) + if (key_exchange_is_ecdh(algs->dh)) { return supported_ec_group(this, algs->dh); } return algs->dh; } - return MODP_NONE; + return KE_NONE; } METHOD(tls_crypto_t, set_protection, void, @@ -2494,16 +2494,16 @@ int tls_crypto_get_supported_suites(bool null, tls_version_t version, /** * See header. */ -int tls_crypto_get_supported_groups(diffie_hellman_group_t **out) +int tls_crypto_get_supported_groups(key_exchange_method_t **out) { enumerator_t *enumerator; - diffie_hellman_group_t groups[countof(curves)]; - diffie_hellman_group_t group; + key_exchange_method_t groups[countof(curves)]; + key_exchange_method_t group; tls_named_group_t curve; int count = 0, i; enumerator = enumerator_create_filter( - lib->crypto->create_dh_enumerator(lib->crypto), + lib->crypto->create_ke_enumerator(lib->crypto), group_filter, NULL, NULL); while (enumerator->enumerate(enumerator, &group, &curve)) @@ -2514,7 +2514,7 @@ int tls_crypto_get_supported_groups(diffie_hellman_group_t **out) if (out) { - *out = calloc(count, sizeof(diffie_hellman_group_t)); + *out = calloc(count, sizeof(key_exchange_method_t)); for (i = 0; i < count; i++) { (*out)[i] = groups[i]; @@ -2565,7 +2565,7 @@ int tls_crypto_get_supported_signatures(tls_version_t version, /** * See header. */ -tls_named_group_t tls_ec_group_to_curve(diffie_hellman_group_t group) +tls_named_group_t tls_ec_group_to_curve(key_exchange_method_t group) { int i; diff --git a/src/libtls/tls_crypto.h b/src/libtls/tls_crypto.h index c7efaf1ef..42d308754 100644 --- a/src/libtls/tls_crypto.h +++ b/src/libtls/tls_crypto.h @@ -464,9 +464,9 @@ struct tls_crypto_t { /** * Get the Diffie-Hellman group to use, if any. * - * @return Diffie Hellman group, ord MODP_NONE + * @return Diffie-Hellman group, or KE_NONE */ - diffie_hellman_group_t (*get_dh_group)(tls_crypto_t *this); + key_exchange_method_t (*get_dh_group)(tls_crypto_t *this); /** * Write the list of supported signature schemes, either for certificates @@ -481,7 +481,7 @@ struct tls_crypto_t { /** * Create an enumerator over supported ECDH groups. * - * Enumerates over (diffie_hellman_group_t, tls_named_group_t) + * Enumerates over (key_exchange_method_t, tls_named_group_t) * * @return enumerator */ @@ -680,7 +680,7 @@ int tls_crypto_get_supported_suites(bool null, tls_version_t version, * @param groups pointer to allocated DH group array, to free(), or NULL * @return number of curves supported */ -int tls_crypto_get_supported_groups(diffie_hellman_group_t **groups); +int tls_crypto_get_supported_groups(key_exchange_method_t **groups); /** * Get a list of all supported TLS signature schemes. @@ -698,7 +698,7 @@ int tls_crypto_get_supported_signatures(tls_version_t version, * @param group diffie hellman group indicator * @return TLS group indicator */ -tls_named_group_t tls_ec_group_to_curve(diffie_hellman_group_t group); +tls_named_group_t tls_ec_group_to_curve(key_exchange_method_t group); /** * Get the key type from a TLS signature scheme diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index 5544ee6e1..04f4bcb37 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -123,7 +123,7 @@ struct private_tls_peer_t { /** * DHE exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Requested DH group @@ -162,7 +162,7 @@ struct private_tls_peer_t { }; /* Implemented in tls_server.c */ -bool tls_write_key_share(bio_writer_t **key_share, diffie_hellman_t *dh); +bool tls_write_key_share(bio_writer_t **key_share, key_exchange_t *dh); public_key_t *tls_find_public_key(auth_cfg_t *peer_auth, identification_t *id); /** @@ -172,7 +172,7 @@ static bool verify_requested_key_type(private_tls_peer_t *this, uint16_t key_type) { enumerator_t *enumerator; - diffie_hellman_group_t group, found = MODP_NONE; + key_exchange_method_t group, found = KE_NONE; tls_named_group_t curve; enumerator = this->crypto->create_ec_enumerator(this->crypto); @@ -186,12 +186,12 @@ static bool verify_requested_key_type(private_tls_peer_t *this, } enumerator->destroy(enumerator); - if (found == MODP_NONE) + if (found == KE_NONE) { DBG1(DBG_TLS, "server requested key exchange we didn't propose"); return FALSE; } - if (this->dh->get_dh_group(this->dh) == found) + if (this->dh->get_method(this->dh) == found) { DBG1(DBG_TLS, "server requested key exchange we already use"); return FALSE; @@ -426,7 +426,7 @@ static status_t process_server_hello(private_tls_peer_t *this, key_share = chunk_skip(key_share, 1); } if (!key_share.len || - !this->dh->set_other_public_value(this->dh, key_share) || + !this->dh->set_public_key(this->dh, key_share) || !this->dh->get_shared_secret(this->dh, &shared_secret) || !this->crypto->derive_handshake_keys(this->crypto, shared_secret)) { @@ -676,7 +676,7 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this, public->destroy(public); free(chunk.ptr); - this->dh = lib->crypto->create_dh(lib->crypto, MODP_CUSTOM, + this->dh = lib->crypto->create_ke(lib->crypto, MODP_CUSTOM, generator, prime); if (!this->dh) { @@ -684,7 +684,7 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - if (!this->dh->set_other_public_value(this->dh, pub)) + if (!this->dh->set_public_key(this->dh, pub)) { DBG1(DBG_TLS, "applying DH public value failed"); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); @@ -698,10 +698,10 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this, /** * Get the EC group for a TLS named curve */ -static diffie_hellman_group_t curve_to_ec_group(private_tls_peer_t *this, - tls_named_group_t curve) +static key_exchange_method_t curve_to_ec_group(private_tls_peer_t *this, + tls_named_group_t curve) { - diffie_hellman_group_t group; + key_exchange_method_t group; tls_named_group_t current; enumerator_t *enumerator; @@ -724,7 +724,7 @@ static diffie_hellman_group_t curve_to_ec_group(private_tls_peer_t *this, static status_t process_ec_key_exchange(private_tls_peer_t *this, bio_reader_t *reader) { - diffie_hellman_group_t group; + key_exchange_method_t group; public_key_t *public; uint8_t type; uint16_t curve; @@ -783,11 +783,11 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this, public->destroy(public); free(chunk.ptr); - this->dh = lib->crypto->create_dh(lib->crypto, group); + this->dh = lib->crypto->create_ke(lib->crypto, group); if (!this->dh) { DBG1(DBG_TLS, "DH group %N not supported", - diffie_hellman_group_names, group); + key_exchange_method_names, group); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } @@ -805,7 +805,7 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this, pub = chunk_skip(pub, 1); } - if (!this->dh->set_other_public_value(this->dh, pub)) + if (!this->dh->set_public_key(this->dh, pub)) { DBG1(DBG_TLS, "applying DH public value failed"); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); @@ -822,20 +822,20 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this, static status_t process_key_exchange(private_tls_peer_t *this, bio_reader_t *reader) { - diffie_hellman_group_t group; + key_exchange_method_t group; this->crypto->append_handshake(this->crypto, TLS_SERVER_KEY_EXCHANGE, reader->peek(reader)); group = this->crypto->get_dh_group(this->crypto); - if (group == MODP_NONE) + if (group == KE_NONE) { DBG1(DBG_TLS, "received Server Key Exchange, but not required " "for current suite"); this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); return NEED_MORE; } - if (diffie_hellman_group_is_ec(group)) + if (key_exchange_is_ecdh(group)) { return process_ec_key_exchange(this, reader); } @@ -1248,7 +1248,7 @@ static status_t send_client_hello(private_tls_peer_t *this, tls_cipher_suite_t *suites; bio_writer_t *extensions, *curves = NULL, *versions, *key_share, *signatures; tls_version_t version_max, version_min; - diffie_hellman_group_t group; + key_exchange_method_t group; tls_named_group_t curve; enumerator_t *enumerator; int count, i, v; @@ -1336,7 +1336,7 @@ static status_t send_client_hello(private_tls_peer_t *this, } if (!this->dh) { - this->dh = lib->crypto->create_dh(lib->crypto, group); + this->dh = lib->crypto->create_ke(lib->crypto, group); if (!this->dh) { continue; @@ -1636,12 +1636,12 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this, } chunk_clear(&premaster); - if (!this->dh->get_my_public_value(this->dh, &pub)) + if (!this->dh->get_public_key(this->dh, &pub)) { this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - switch (this->dh->get_dh_group(this->dh)) + switch (this->dh->get_method(this->dh)) { case MODP_CUSTOM: writer->write_data16(writer, pub); diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index 26899dc1c..97c4c40da 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -121,7 +121,7 @@ struct private_tls_server_t { /** * DHE exchange */ - diffie_hellman_t *dh; + key_exchange_t *dh; /** * Requested DH group @@ -571,7 +571,7 @@ static status_t process_client_hello(private_tls_server_t *this, if (this->tls->get_version_max(this->tls) >= TLS_1_3) { - diffie_hellman_group_t group; + key_exchange_method_t group; tls_named_group_t curve, requesting_curve = 0; enumerator_t *enumerator; array_t *peer_key_shares; @@ -609,7 +609,7 @@ static status_t process_client_hello(private_tls_server_t *this, { DBG1(DBG_TLS, "using key exchange %N", tls_named_group_names, curve); - this->dh = lib->crypto->create_dh(lib->crypto, group); + this->dh = lib->crypto->create_ke(lib->crypto, group); break; } } @@ -656,7 +656,7 @@ static status_t process_client_hello(private_tls_server_t *this, peer.key_share = chunk_skip(peer.key_share, 1); } if (!peer.key_share.len || - !this->dh->set_other_public_value(this->dh, peer.key_share)) + !this->dh->set_public_key(this->dh, peer.key_share)) { DBG1(DBG_TLS, "DH key derivation failed"); this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); @@ -844,14 +844,14 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this, bio_reader_t *reader) { chunk_t premaster, pub; - diffie_hellman_group_t group; + key_exchange_method_t group; bool ec; this->crypto->append_handshake(this->crypto, TLS_CLIENT_KEY_EXCHANGE, reader->peek(reader)); - group = this->dh->get_dh_group(this->dh); - ec = diffie_hellman_group_is_ec(group); + group = this->dh->get_method(this->dh); + ec = key_exchange_is_ecdh(group); if ((ec && !reader->read_data8(reader, &pub)) || (!ec && (!reader->read_data16(reader, &pub) || pub.len == 0))) { @@ -873,7 +873,7 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this, } pub = chunk_skip(pub, 1); } - if (!this->dh->set_other_public_value(this->dh, pub)) + if (!this->dh->set_public_key(this->dh, pub)) { DBG1(DBG_TLS, "applying DH public value failed"); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); @@ -1154,7 +1154,7 @@ METHOD(tls_handshake_t, process, status_t, /** * Write public key into key share extension */ -bool tls_write_key_share(bio_writer_t **key_share, diffie_hellman_t *dh) +bool tls_write_key_share(bio_writer_t **key_share, key_exchange_t *dh) { bio_writer_t *writer; tls_named_group_t curve; @@ -1164,8 +1164,8 @@ bool tls_write_key_share(bio_writer_t **key_share, diffie_hellman_t *dh) { return FALSE; } - curve = tls_ec_group_to_curve(dh->get_dh_group(dh)); - if (!curve || !dh->get_my_public_value(dh, &pub)) + curve = tls_ec_group_to_curve(dh->get_method(dh)); + if (!curve || !dh->get_public_key(dh, &pub)) { return FALSE; } @@ -1496,13 +1496,13 @@ static bool find_supported_curve(private_tls_server_t *this, */ static status_t send_server_key_exchange(private_tls_server_t *this, tls_handshake_type_t *type, bio_writer_t *writer, - diffie_hellman_group_t group) + key_exchange_method_t group) { diffie_hellman_params_t *params = NULL; tls_named_group_t curve; chunk_t chunk; - if (diffie_hellman_group_is_ec(group)) + if (key_exchange_is_ecdh(group)) { curve = tls_ec_group_to_curve(group); if (!curve || (!peer_supports_curve(this, curve) && @@ -1522,23 +1522,23 @@ static status_t send_server_key_exchange(private_tls_server_t *this, if (!params) { DBG1(DBG_TLS, "no parameters found for DH group %N", - diffie_hellman_group_names, group); + key_exchange_method_names, group); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - DBG2(DBG_TLS, "selected DH group %N", diffie_hellman_group_names, group); + DBG2(DBG_TLS, "selected DH group %N", key_exchange_method_names, group); writer->write_data16(writer, params->prime); writer->write_data16(writer, params->generator); } - this->dh = lib->crypto->create_dh(lib->crypto, group); + this->dh = lib->crypto->create_ke(lib->crypto, group); if (!this->dh) { DBG1(DBG_TLS, "DH group %N not supported", - diffie_hellman_group_names, group); + key_exchange_method_names, group); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - if (!this->dh->get_my_public_value(this->dh, &chunk)) + if (!this->dh->get_public_key(this->dh, &chunk)) { this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; @@ -1649,7 +1649,7 @@ static status_t send_key_update(private_tls_server_t *this, METHOD(tls_handshake_t, build, status_t, private_tls_server_t *this, tls_handshake_type_t *type, bio_writer_t *writer) { - diffie_hellman_group_t group; + key_exchange_method_t group; if (this->tls->get_version_max(this->tls) < TLS_1_3) { diff --git a/src/libtpmtss/tpm_tss_tss2_session.c b/src/libtpmtss/tpm_tss_tss2_session.c index baf3a4246..12123803f 100644 --- a/src/libtpmtss/tpm_tss_tss2_session.c +++ b/src/libtpmtss/tpm_tss_tss2_session.c @@ -650,8 +650,8 @@ static bool kdf_e(TPMI_ALG_HASH hash_alg, chunk_t z, chunk_t label, static bool ecc_salt(TPM2B_PUBLIC *public, TPMI_ALG_HASH hash_alg, chunk_t *secret, TPM2B_ENCRYPTED_SECRET *encryptedSalt) { - diffie_hellman_group_t ec_group; - diffie_hellman_t *dh; + key_exchange_method_t ec_ke_method; + key_exchange_t *ke; chunk_t ecdh_pubkey = chunk_empty, ecdh_pubkey_x, ecdh_pubkey_y; chunk_t ecc_pubkey = chunk_empty, ecc_pubkey_x, ecc_pubkey_y; chunk_t z = chunk_empty; @@ -663,13 +663,13 @@ static bool ecc_salt(TPM2B_PUBLIC *public, TPMI_ALG_HASH hash_alg, switch (public->publicArea.parameters.eccDetail.curveID) { case TPM2_ECC_NIST_P256: - ec_group = ECP_256_BIT; + ec_ke_method = ECP_256_BIT; break; case TPM2_ECC_NIST_P384: - ec_group = ECP_384_BIT; + ec_ke_method = ECP_384_BIT; break; case TPM2_ECC_NIST_P521: - ec_group = ECP_521_BIT; + ec_ke_method = ECP_521_BIT; break; default: DBG1(DBG_PTS, "type of ECC EK key not supported"); @@ -677,16 +677,16 @@ static bool ecc_salt(TPM2B_PUBLIC *public, TPMI_ALG_HASH hash_alg, } /* Generate ECDH key pair */ - dh = lib->crypto->create_dh(lib->crypto, ec_group); - if (!dh) + ke = lib->crypto->create_ke(lib->crypto, ec_ke_method); + if (!ke) { DBG1(DBG_PTS, "DH group could not be created"); return FALSE; } - if (!dh->get_my_public_value(dh, &ecdh_pubkey)) + if (!ke->get_public_key(ke, &ecdh_pubkey)) { DBG1(DBG_PTS, "DH public key could not be generated"); - dh->destroy(dh); + ke->destroy(ke); return FALSE; } ecdh_pubkey_x = chunk_create(ecdh_pubkey.ptr, ecdh_pubkey.len / 2); @@ -701,12 +701,12 @@ static bool ecc_salt(TPM2B_PUBLIC *public, TPMI_ALG_HASH hash_alg, ecc_pubkey = chunk_cat("cc", ecc_pubkey_x, ecc_pubkey_y); /* compute point multiplication of ecc_pubkey with ecdh_privkey */ - if (!dh->set_other_public_value(dh, ecc_pubkey)) + if (!ke->set_public_key(ke, ecc_pubkey)) { DBG1(DBG_PTS, "ECC public could not be set"); goto error; } - if (!dh->get_shared_secret(dh, &z)) + if (!ke->get_shared_secret(ke, &z)) { DBG1(DBG_PTS, "could not create shared secret"); goto error; @@ -736,7 +736,7 @@ static bool ecc_salt(TPM2B_PUBLIC *public, TPMI_ALG_HASH hash_alg, success = TRUE; error: - dh->destroy(dh); + ke->destroy(ke); chunk_free(&ecdh_pubkey); chunk_free(&ecc_pubkey); chunk_clear(&z);