Also includes ESA flags.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
#include "tkm.h"
#include "tkm_nonceg.h"
-#include "tkm_diffie_hellman.h"
+#include "tkm_key_exchange.h"
#include "tkm_keymat.h"
#include "tkm_listener.h"
#include "tkm_kernel_ipsec.h"
lib->plugins->add_static_features(lib->plugins, "tkm-backend", features,
countof(features), TRUE, NULL, NULL);
- if (!register_dh_mapping())
+ if (!register_ke_mapping())
{
- DBG1(DBG_DMN, "no DH group mapping defined - aborting %s", dmn_name);
+ DBG1(DBG_DMN, "no KE group mapping defined - aborting %s", dmn_name);
goto deinit;
}
lib->encoding->remove_encoder(lib->encoding, tkm_encoder_encode);
deinit:
- destroy_dh_mapping();
+ destroy_ke_mapping();
destroy_ca_mapping();
libcharon_deinit();
tkm_deinit();
}
/* get limits from tkm */
- if (ike_tkm_limits(&max_requests, &limits[TKM_CTX_NONCE], &limits[TKM_CTX_DH],
+ if (ike_tkm_limits(&max_requests, &limits[TKM_CTX_NONCE], &limits[TKM_CTX_KE],
&limits[TKM_CTX_CC], &limits[TKM_CTX_AE],
- &limits[TKM_CTX_ISA], &limits[TKM_CTX_ESA]) != TKM_OK)
+ &limits[TKM_CTX_ISA], &limits[TKM_CTX_ESA],
+ &limits[TKM_CTX_BLOB]) != TKM_OK)
{
ees_server_finalize();
tkmlib_final();
#include <utils/debug.h>
#include <threading/rwlock.h>
-ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA,
+ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_BLOB,
"NONCE_CONTEXT",
"DH_CONTEXT",
"CC_CONTEXT",
"ISA_CONTEXT",
"AE_CONTEXT",
- "ESA_CONTEXT");
-ENUM_END(tkm_context_kind_names, TKM_CTX_ESA);
+ "ESA_CONTEXT",
+ "BLOB_CONTEXT");
+ENUM_END(tkm_context_kind_names, TKM_CTX_BLOB);
typedef struct private_tkm_id_manager_t private_tkm_id_manager_t;
enum tkm_context_kind_t {
/** Nonce context */
TKM_CTX_NONCE,
- /** Diffie-Hellman context */
- TKM_CTX_DH,
+ /** Key Exchange context */
+ TKM_CTX_KE,
/** Certificate chain context */
TKM_CTX_CC,
/** IKE SA context */
TKM_CTX_AE,
/** ESP SA context */
TKM_CTX_ESA,
+ /** Blob context */
+ TKM_CTX_BLOB,
/** helper to determine the number of elements in this enum */
TKM_CTX_MAX,
kernel_ipsec_add_sa_t *data)
{
esa_info_t esa;
+ esa_flags_type flags;
esp_spi_type spi_loc, spi_rem;
host_t *local, *peer;
chunk_t *nonce_loc, *nonce_rem;
{
nonce_loc = &esa.nonce_i;
nonce_rem = &esa.nonce_r;
+ flags = TKM_ESA_INITIATOR;
}
else
{
nonce_loc = &esa.nonce_r;
nonce_rem = &esa.nonce_i;
+ flags = 0;
}
esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA);
/*
* creation of first CHILD SA:
- * no nonce and no dh contexts because the ones from the IKE SA are re-used
+ * no nonce and no ke contexts because the ones from the IKE SA are re-used
*/
nonce_loc_id = tkm->chunk_map->get_id(tkm->chunk_map, nonce_loc);
- if (nonce_loc_id == 0 && esa.dh_id == 0)
+ if (nonce_loc_id == 0 && esa.ke_ids.size == 0)
{
- if (ike_esa_create_first(esa_id, esa.isa_id, data->reqid, 1, spi_loc,
- spi_rem) != TKM_OK)
+ if (ike_esa_create_first(esa_id, esa.isa_id, data->reqid, 1, flags,
+ spi_loc, spi_rem) != TKM_OK)
{
DBG1(DBG_KNL, "child SA (%llu, first) creation failed", esa_id);
goto failure;
}
}
- /* creation of child SA without PFS: no dh context */
- else if (nonce_loc_id != 0 && esa.dh_id == 0)
+ /* creation of child SA without PFS: no ke context */
+ else if (nonce_loc_id != 0 && esa.ke_ids.size == 0)
{
chunk_to_sequence(nonce_rem, &nc_rem, sizeof(nonce_type));
if (ike_esa_create_no_pfs(esa_id, esa.isa_id, data->reqid, 1,
- nonce_loc_id, nc_rem, data->initiator,
+ nonce_loc_id, nc_rem, flags,
spi_loc, spi_rem) != TKM_OK)
{
DBG1(DBG_KNL, "child SA (%llu, no PFS) creation failed", esa_id);
tkm->chunk_map->remove(tkm->chunk_map, nonce_loc);
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
}
- /* creation of subsequent child SA with PFS: nonce and dh context are set */
+ /* creation of subsequent child SA with PFS: nonce and ke context are set */
else
{
chunk_to_sequence(nonce_rem, &nc_rem, sizeof(nonce_type));
- if (ike_esa_create(esa_id, esa.isa_id, data->reqid, 1, esa.dh_id,
- nonce_loc_id, nc_rem, data->initiator, spi_loc,
+ if (ike_esa_create(esa_id, esa.isa_id, data->reqid, 1, esa.ke_ids,
+ nonce_loc_id, nc_rem, flags, spi_loc,
spi_rem) != TKM_OK)
{
DBG1(DBG_KNL, "child SA (%llu) creation failed", esa_id);
#include "tkm.h"
#include "tkm_utils.h"
-#include "tkm_diffie_hellman.h"
+#include "tkm_key_exchange.h"
#include <daemon.h>
#include <collections/hashtable.h>
-typedef struct private_tkm_diffie_hellman_t private_tkm_diffie_hellman_t;
+typedef struct private_tkm_key_exchange_t private_tkm_key_exchange_t;
-static hashtable_t *group_map = NULL;
+static hashtable_t *method_map = NULL;
/**
- * Private data of a tkm_diffie_hellman_t object.
+ * Private data of a tkm_key_exchange_t object.
*/
-struct private_tkm_diffie_hellman_t {
+struct private_tkm_key_exchange_t {
/**
- * Public tkm_diffie_hellman_t interface.
+ * Public tkm_key_exchange_t interface.
*/
- tkm_diffie_hellman_t public;
+ tkm_key_exchange_t public;
/**
- * Diffie-Hellman group number.
+ * Key exchange method identifier.
*/
- key_exchange_method_t group;
+ key_exchange_method_t method;
/**
- * Diffie-Hellman public value.
+ * Key exchange algorithm ID corresponding to method.
*/
- dh_pubvalue_type pubvalue;
+ uint64_t kea_id;
/**
* Context id.
*/
- dh_id_type context_id;
+ ke_id_type context_id;
};
METHOD(key_exchange_t, get_public_key, bool,
- private_tkm_diffie_hellman_t *this, chunk_t *value)
+ private_tkm_key_exchange_t *this, chunk_t *value)
{
- sequence_to_chunk(this->pubvalue.data, this->pubvalue.size, value);
- return TRUE;
+ blob_id_type pubvalue_id;
+ blob_length_type pubvalue_length;
+ bool ret = FALSE;
+
+ pubvalue_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_BLOB);
+ if (pubvalue_id)
+ {
+ ret = ike_ke_get(this->context_id, this->kea_id, pubvalue_id,
+ &pubvalue_length) == TKM_OK &&
+ blob_to_chunk(pubvalue_id, pubvalue_length, value);
+
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_BLOB, pubvalue_id);
+ }
+ return ret;
}
METHOD(key_exchange_t, get_shared_secret, bool,
- private_tkm_diffie_hellman_t *this, chunk_t *secret)
+ private_tkm_key_exchange_t *this, chunk_t *secret)
{
*secret = chunk_empty;
return TRUE;
}
METHOD(key_exchange_t, set_public_key, bool,
- private_tkm_diffie_hellman_t *this, chunk_t value)
+ private_tkm_key_exchange_t *this, chunk_t value)
{
- dh_pubvalue_type othervalue;
+ blob_id_type pubvalue_id;
+ bool ret = FALSE;
- if (!key_exchange_verify_pubkey(this->group, value) ||
- value.len > sizeof(othervalue.data))
+ if (!key_exchange_verify_pubkey(this->method, value))
{
return FALSE;
}
- othervalue.size = value.len;
- memcpy(&othervalue.data, value.ptr, value.len);
- return ike_dh_generate_key(this->context_id, othervalue) == TKM_OK;
+ pubvalue_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_BLOB);
+ if (pubvalue_id)
+ {
+ ret = chunk_to_blob(pubvalue_id, &value) &&
+ ike_ke_set(this->context_id, this->kea_id, pubvalue_id) == TKM_OK;
+
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_BLOB, pubvalue_id);
+ }
+ return ret;
}
METHOD(key_exchange_t, get_method, key_exchange_method_t,
- private_tkm_diffie_hellman_t *this)
+ private_tkm_key_exchange_t *this)
{
- return this->group;
+ return this->method;
}
METHOD(key_exchange_t, destroy, void,
- private_tkm_diffie_hellman_t *this)
+ private_tkm_key_exchange_t *this)
{
- if (ike_dh_reset(this->context_id) != TKM_OK)
+ if (ike_ke_reset(this->context_id) != TKM_OK)
{
- DBG1(DBG_LIB, "failed to reset DH context %d", this->context_id);
+ DBG1(DBG_LIB, "failed to reset KE context %d", this->context_id);
}
- tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_DH, this->context_id);
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_KE, this->context_id);
free(this);
}
-METHOD(tkm_diffie_hellman_t, get_id, dh_id_type,
- private_tkm_diffie_hellman_t *this)
+METHOD(tkm_key_exchange_t, get_id, ke_id_type,
+ private_tkm_key_exchange_t *this)
{
return this->context_id;
}
/*
* Described in header.
*/
-int register_dh_mapping()
+int register_ke_mapping()
{
int count, i;
char *iana_id_str, *tkm_id_str;
(hashtable_equals_t)equals, 16);
enumerator = lib->settings->create_key_value_enumerator(lib->settings,
- "%s.dh_mapping",
+ "%s.ke_mapping",
lib->ns);
while (enumerator->enumerate(enumerator, &iana_id_str, &tkm_id_str))
count = map->get_count(map);
plugin_feature_t f[count + 1];
- f[0] = PLUGIN_REGISTER(KE, tkm_diffie_hellman_create);
+ f[0] = PLUGIN_REGISTER(KE, tkm_key_exchange_create);
i = 1;
enumerator = map->create_enumerator(map);
}
enumerator->destroy(enumerator);
- lib->plugins->add_static_features(lib->plugins, "tkm-dh", f, countof(f),
+ lib->plugins->add_static_features(lib->plugins, "tkm-ke", f, countof(f),
TRUE, NULL, NULL);
if (count > 0)
{
- group_map = map;
+ method_map = map;
}
else
{
/*
* Described in header.
*/
-void destroy_dh_mapping()
+void destroy_ke_mapping()
{
enumerator_t *enumerator;
char *key, *value;
- if (group_map)
+ if (method_map)
{
- enumerator = group_map->create_enumerator(group_map);
+ enumerator = method_map->create_enumerator(method_map);
while (enumerator->enumerate(enumerator, &key, &value))
{
free(key);
free(value);
}
enumerator->destroy(enumerator);
- group_map->destroy(group_map);
+ method_map->destroy(method_map);
+ method_map = NULL;
}
}
/*
* Described in header.
*/
-tkm_diffie_hellman_t *tkm_diffie_hellman_create(key_exchange_method_t group)
+tkm_key_exchange_t *tkm_key_exchange_create(key_exchange_method_t method)
{
- private_tkm_diffie_hellman_t *this;
+ private_tkm_key_exchange_t *this;
- if (!group_map)
+ if (!method_map)
{
return NULL;
}
},
.get_id = _get_id,
},
- .group = group,
- .context_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_DH),
+ .method = method,
+ .context_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_KE),
);
if (!this->context_id)
return NULL;
}
- uint64_t *dha_id = group_map->get(group_map, &group);
- if (!dha_id)
+ uint64_t *kea_id_ptr = method_map->get(method_map, &method);
+ if (!kea_id_ptr)
{
free(this);
return NULL;
}
- if (ike_dh_create(this->context_id, *dha_id, &this->pubvalue) != TKM_OK)
- {
- free(this);
- return NULL;
- }
+ this->kea_id = *kea_id_ptr;
return &this->public;
}
*/
/**
- * @defgroup tkm-dh diffie hellman
+ * @defgroup tkm-ke key exchange
* @{ @ingroup tkm
*/
-#ifndef TKM_DIFFIE_HELLMAN_H_
-#define TKM_DIFFIE_HELLMAN_H_
+#ifndef TKM_KEY_EXCHANGE_H_
+#define TKM_KEY_EXCHANGE_H_
-typedef struct tkm_diffie_hellman_t tkm_diffie_hellman_t;
+typedef struct tkm_key_exchange_t tkm_key_exchange_t;
#include <library.h>
#include <tkm/types.h>
/**
* key_exchange_t implementation using the trusted key manager.
*/
-struct tkm_diffie_hellman_t {
+struct tkm_key_exchange_t {
/**
* Implements key_exchange_t interface.
key_exchange_t ke;
/**
- * Get Diffie-Hellman context id.
+ * Get Key Exchange context id.
*
- * @return id of this DH context.
+ * @return id of this KE context.
*/
- dh_id_type (*get_id)(tkm_diffie_hellman_t * const this);
+ ke_id_type (*get_id)(tkm_key_exchange_t * const this);
};
/**
- * Loads IANA DH group identifier to TKM id mapping from config and registers
- * the corresponding DH features.
+ * Loads IANA KE method identifier to TKM id mapping from config and registers
+ * the corresponding KE plugin features.
*
* @return number of registered mappings
*/
-int register_dh_mapping();
+int register_ke_mapping();
/**
- * Destroy IANA DH group identifier to TKM id mapping.
+ * Destroy IANA KE method identifier to TKM id mapping.
*/
-void destroy_dh_mapping();
+void destroy_ke_mapping();
/**
- * Creates a new tkm_diffie_hellman_t object.
+ * Creates a new tkm_key_exchange_t object.
*
- * @param group Diffie Hellman group number to use
- * @return tkm_diffie_hellman_t object, NULL if not supported
+ * @param method Key exchange method to use
+ * @return tkm_key_exchange_t object, NULL if not supported
*/
-tkm_diffie_hellman_t *tkm_diffie_hellman_create(key_exchange_method_t group);
+tkm_key_exchange_t *tkm_key_exchange_create(key_exchange_method_t method);
-#endif /** TKM_DIFFIE_HELLMAN_H_ @}*/
+#endif /** TKM_KEY_EXCHANGE_H_ @}*/
#include "tkm.h"
#include "tkm_types.h"
#include "tkm_utils.h"
-#include "tkm_diffie_hellman.h"
+#include "tkm_key_exchange.h"
#include "tkm_keymat.h"
#include "tkm_aead.h"
return lib->crypto->create_nonce_gen(lib->crypto);
}
+/**
+ * Concatenate the TKM KE IDs of the passed key exchanges
+ */
+static bool concat_ke_ids(array_t *kes, ke_ids_type *ids)
+{
+ tkm_key_exchange_t *tkm_ke;
+ uint32_t i;
+
+ memset(ids, 0, sizeof(*ids));
+ ids->size = array_count(kes);
+
+ if (!ids->size || ids->size > 8)
+ {
+ return FALSE;
+ }
+
+ for (i = 0; i < ids->size; i++)
+ {
+ array_get(kes, i, &tkm_ke);
+ ids->data[i] = tkm_ke->get_id(tkm_ke);
+ }
+ return TRUE;
+}
+
METHOD(keymat_v2_t, derive_ike_keys, bool,
private_tkm_keymat_t *this, proposal_t *proposal, array_t *kes,
chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
pseudo_random_function_t rekey_function, chunk_t rekey_skd)
{
- uint64_t nc_id, spi_loc, spi_rem;
+ uint64_t nc_id = 0, spi_loc, spi_rem;
chunk_t *nonce;
- tkm_diffie_hellman_t *tkm_dh;
- key_exchange_t *ke;
- dh_id_type dh_id;
+ ke_ids_type ke_ids;
nonce_type nonce_rem;
result_type res;
block_len_type block_len;
icv_len_type icv_len;
iv_len_type iv_len;
- if (array_count(kes) != 1)
+ if (!concat_ke_ids(kes, &ke_ids))
{
- DBG1(DBG_IKE, "the TKM currently only supports a single key exchange");
return FALSE;
}
- /* Acquire nonce context id */
nonce = this->initiator ? &nonce_i : &nonce_r;
- nc_id = tkm->chunk_map->get_id(tkm->chunk_map, nonce);
- if (!nc_id)
- {
- DBG1(DBG_IKE, "unable to acquire context id for nonce");
- return FALSE;
- }
-
- /* Get DH context id */
- array_get(kes, ARRAY_HEAD, &ke);
- tkm_dh = (tkm_diffie_hellman_t *)ke;
- dh_id = tkm_dh->get_id(tkm_dh);
if (this->initiator)
{
if (rekey_function == PRF_UNDEFINED)
{
+ /* Acquire nonce context id */
+ nc_id = tkm->chunk_map->get_id(tkm->chunk_map, nonce);
+ if (!nc_id)
+ {
+ DBG1(DBG_IKE, "unable to acquire context id for nonce");
+ return FALSE;
+ }
+
this->ae_ctx_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_AE);
if (!this->ae_ctx_id)
{
DBG1(DBG_IKE, "unable to acquire ae context id");
return FALSE;
}
- DBG1(DBG_IKE, "deriving IKE keys (nc: %llu, dh: %llu, spi_loc: %llx, "
- "spi_rem: %llx)", nc_id, dh_id, spi_loc, spi_rem);
- res = ike_isa_create(this->isa_ctx_id, this->ae_ctx_id, 1, dh_id, nc_id,
- nonce_rem, this->initiator, spi_loc, spi_rem,
+ DBG1(DBG_IKE, "deriving IKE keys (nc: %llu, ke: %llu, spi_loc: %llx, "
+ "spi_rem: %llx)", nc_id, ke_ids.data[0], spi_loc, spi_rem);
+ res = ike_isa_create(this->isa_ctx_id, this->ae_ctx_id, 1, ke_ids.data[0],
+ nc_id, nonce_rem, this->initiator, spi_loc, spi_rem,
&block_len, &icv_len, &iv_len);
}
else
return FALSE;
}
isa_info = *((isa_info_t *)(rekey_skd.ptr));
- DBG1(DBG_IKE, "deriving IKE keys (parent_isa: %llu, ae: %llu, nc: %llu,"
- " dh: %llu, spi_loc: %llx, spi_rem: %llx)", isa_info.parent_isa_id,
- isa_info.ae_id, nc_id, dh_id, spi_loc, spi_rem);
- if (!tkm->idmgr->acquire_ref(tkm->idmgr, TKM_CTX_AE, isa_info.ae_id))
+ if (this->ae_ctx_id == isa_info.ae_id)
+ {
+ DBG1(DBG_IKE, "deriving IKE keys (parent_isa: %llu, ae: %llu, "
+ "ke: %llu, spi_loc: %llx, spi_rem: %llx)", isa_info.parent_isa_id,
+ isa_info.ae_id, ke_ids.data[0], spi_loc, spi_rem);
+
+ res = ike_isa_update(this->isa_ctx_id, ke_ids.data[0]);
+ }
+ else if (!(nc_id = tkm->chunk_map->get_id(tkm->chunk_map, nonce)))
+ {
+ DBG1(DBG_IKE, "unable to acquire context id for nonce");
+ return FALSE;
+ }
+ else if (!tkm->idmgr->acquire_ref(tkm->idmgr, TKM_CTX_AE, isa_info.ae_id))
{
DBG1(DBG_IKE, "unable to acquire reference for ae: %llu",
isa_info.ae_id);
return FALSE;
}
- this->ae_ctx_id = isa_info.ae_id;
- res = ike_isa_create_child(this->isa_ctx_id, isa_info.parent_isa_id, 1,
- dh_id, nc_id, nonce_rem, this->initiator,
- spi_loc, spi_rem, &block_len, &icv_len,
- &iv_len);
+ else
+ {
+ DBG1(DBG_IKE, "deriving IKE keys (parent_isa: %llu, ae: %llu, nc: %llu, "
+ "ke: %llu, spi_loc: %llx, spi_rem: %llx)", isa_info.parent_isa_id,
+ isa_info.ae_id, nc_id, ke_ids.data[0], spi_loc, spi_rem);
+
+ this->ae_ctx_id = isa_info.ae_id;
+ res = ike_isa_create_child(this->isa_ctx_id, isa_info.parent_isa_id, 1,
+ ke_ids, nc_id, nonce_rem, this->initiator,
+ spi_loc, spi_rem, &block_len, &icv_len,
+ &iv_len);
+ }
+
chunk_free(&rekey_skd);
}
+ if (nc_id)
+ {
+ tkm->chunk_map->remove(tkm->chunk_map, nonce);
+ if (ike_nc_reset(nc_id) != TKM_OK)
+ {
+ DBG1(DBG_IKE, "failed to reset nonce context %llu", nc_id);
+ }
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nc_id);
+ }
+
if (res != TKM_OK)
{
DBG1(DBG_IKE, "key derivation failed (isa: %llu)", this->isa_ctx_id);
return FALSE;
}
- this->aead = tkm_aead_create(this->isa_ctx_id, block_len, icv_len, iv_len);
-
- /* TODO: Add failure handler (see keymat_v2.c) */
-
- tkm->chunk_map->remove(tkm->chunk_map, nonce);
- if (ike_nc_reset(nc_id) != TKM_OK)
+ if (!this->aead)
{
- DBG1(DBG_IKE, "failed to reset nonce context %llu", nc_id);
+ this->aead = tkm_aead_create(this->isa_ctx_id, block_len, icv_len,
+ iv_len);
}
- tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nc_id);
+
+ /* TODO: Add failure handler (see keymat_v2.c) */
return TRUE;
}
chunk_t *encr_r, chunk_t *integ_r)
{
esa_info_t *esa_info_i, *esa_info_r;
- dh_id_type dh_id = 0;
- key_exchange_t *ke;
+ ke_ids_type ke_ids = {};
- if (kes && array_get(kes, ARRAY_HEAD, &ke))
+ if (kes && !concat_ke_ids(kes, &ke_ids))
{
- dh_id = ((tkm_diffie_hellman_t *)ke)->get_id((tkm_diffie_hellman_t *)ke);
+ return FALSE;
}
INIT(esa_info_i,
.nonce_i = chunk_clone(nonce_i),
.nonce_r = chunk_clone(nonce_r),
.is_encr_r = FALSE,
- .dh_id = dh_id,
+ .ke_ids = ke_ids,
);
INIT(esa_info_r,
.nonce_i = chunk_clone(nonce_i),
.nonce_r = chunk_clone(nonce_r),
.is_encr_r = TRUE,
- .dh_id = dh_id,
+ .ke_ids = ke_ids,
);
- DBG1(DBG_CHD, "passing on esa info (isa: %llu, spi_l: %x, dh_id: %llu)",
- esa_info_i->isa_id, ntohl(esa_info_i->spi_l), esa_info_i->dh_id);
+ DBG1(DBG_CHD, "passing on esa info (isa: %llu, spi_l: %x, "
+ "ke_id[%llu]: %llu)", esa_info_i->isa_id, ntohl(esa_info_i->spi_l),
+ esa_info_i->ke_ids.size, esa_info_i->ke_ids.data[0]);
/* store ESA info in encr_i/r, which is passed to add_sa */
*encr_i = chunk_create((u_char *)esa_info_i, sizeof(esa_info_t));
private_tkm_keymat_t *this, bool verify, chunk_t data, chunk_t prev,
chunk_t *auth)
{
- DBG1(DBG_IKE, "TKM doesn't support IntAuth calculation");
- return FALSE;
+ blob_id_type data_id;
+ bool ret = FALSE;
+
+ *auth = chunk_empty;
+
+ data_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_BLOB);
+ if (data_id)
+ {
+ ret = chunk_to_blob(data_id, &data) &&
+ ike_isa_int_auth(this->isa_ctx_id, verify, data_id) == TKM_OK;
+
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_BLOB, data_id);
+ }
+ return ret;
}
METHOD(keymat_v2_t, get_auth_octets, bool,
bool is_encr_r;
/**
- * Diffie-Hellman context id.
+ * Key Exchange context ids.
*/
- dh_id_type dh_id;
+ ke_ids_type ke_ids;
};
#include <utils/debug.h>
+#include <tkm/client.h>
+#include <tkm/constants.h>
+
#include "tkm_utils.h"
/* Generic variable-length sequence */
}
memcpy(seq->data, chunk->ptr, seq->size);
}
+
+bool blob_to_chunk(blob_id_type id, blob_length_type len, chunk_t * const chunk)
+{
+ blob_offset_type offset = 0;
+ bool ret = TRUE;
+
+ *chunk = chunk_alloc(len);
+
+ while (len > 0 && ret)
+ {
+ blob_out_bytes_type blob_data;
+ blob_length_type slice_len = min(len, sizeof(blob_data.data));
+
+ ret = ike_blob_read(id, offset, slice_len, &blob_data) == TKM_OK;
+ memcpy(chunk->ptr + offset, blob_data.data, slice_len);
+ offset += slice_len;
+ len -= slice_len;
+ }
+
+ ike_blob_reset(id);
+
+ return ret;
+}
+
+bool chunk_to_blob(blob_id_type id, const chunk_t * const chunk)
+{
+ blob_length_type len = chunk->len;
+ blob_offset_type offset = 0;
+ bool ret;
+
+ ret = ike_blob_create(id, len) == TKM_OK;
+
+ while (len > 0 && ret)
+ {
+ blob_in_bytes_type blob_data;
+ blob_length_type slice_len = min(len, sizeof(blob_data.data));
+
+ memcpy(blob_data.data, chunk->ptr + offset, slice_len);
+ blob_data.size = slice_len;
+ ret = ike_blob_write(id, offset, blob_data) == TKM_OK;
+ offset += slice_len;
+ len -= slice_len;
+ }
+ return ret;
+}
void chunk_to_sequence(const chunk_t * const chunk, void *sequence,
const uint32_t typelen);
+/**
+ * Convert blob to chunk and reset the blob.
+ *
+ * @param id id of blob
+ * @param len length of blob
+ * @param chunk pointer to chunk struct
+ */
+bool blob_to_chunk(blob_id_type id, blob_length_type len, chunk_t * const chunk);
+
+/**
+ * Convert chunk to newly created blob.
+ *
+ * @param id id of blob
+ * @param chunk pointer to chunk struct
+ */
+bool chunk_to_blob(blob_id_type id, const chunk_t * const chunk);
+
#endif /** TKM_UTILS_H_ @}*/
#include "tkm_id_manager.h"
-static const tkm_limits_t limits = {125, 100, 55, 30, 200, 42};
+static const tkm_limits_t limits = {125, 100, 55, 30, 200, 42, 21};
START_TEST(test_id_mgr_creation)
{
#include <daemon.h>
#include <tests/test_suite.h>
-#include "tkm_diffie_hellman.h"
+#include "tkm_key_exchange.h"
-START_TEST(test_dh_creation)
+START_TEST(test_ke_creation)
{
- tkm_diffie_hellman_t *dh = NULL;
+ tkm_key_exchange_t *ke = NULL;
- dh = tkm_diffie_hellman_create(MODP_768_BIT);
- fail_if(dh, "MODP_768 created");
+ ke = tkm_key_exchange_create(MODP_768_BIT);
+ fail_if(ke, "MODP_768 created");
- dh = tkm_diffie_hellman_create(MODP_4096_BIT);
- fail_if(!dh, "MODP_4096 not created");
- fail_if(!dh->get_id(dh), "Invalid context id (0)");
+ ke = tkm_key_exchange_create(MODP_4096_BIT);
+ fail_if(!ke, "MODP_4096 not created");
+ fail_if(!ke->get_id(ke), "Invalid context id (0)");
- dh->ke.destroy(&dh->ke);
+ ke->ke.destroy(&ke->ke);
}
END_TEST
-START_TEST(test_dh_get_my_pubvalue)
+START_TEST(test_ke_get_my_pubvalue)
{
- tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
- fail_if(!dh, "Unable to create DH");
+ tkm_key_exchange_t *ke = tkm_key_exchange_create(MODP_4096_BIT);
+ fail_if(!ke, "Unable to create KE");
chunk_t value;
- ck_assert(dh->ke.get_public_key(&dh->ke, &value));
- dh->ke.destroy(&dh->ke);
+ ck_assert(ke->ke.get_public_key(&ke->ke, &value));
+ ke->ke.destroy(&ke->ke);
fail_if(value.ptr == NULL, "Pubvalue is NULL");
fail_if(value.len != 512, "Pubvalue size mismatch");
}
END_TEST
-Suite *make_diffie_hellman_tests()
+Suite *make_key_exchange_tests()
{
Suite *s;
TCase *tc;
- s = suite_create("Diffie-Hellman");
+ s = suite_create("key exchange");
tc = tcase_create("creation");
- tcase_add_test(tc, test_dh_creation);
+ tcase_add_test(tc, test_ke_creation);
suite_add_tcase(s, tc);
tc = tcase_create("get_my_pubvalue");
- tcase_add_test(tc, test_dh_get_my_pubvalue);
+ tcase_add_test(tc, test_ke_get_my_pubvalue);
suite_add_tcase(s, tc);
return s;
#include "tkm.h"
#include "tkm_nonceg.h"
-#include "tkm_diffie_hellman.h"
+#include "tkm_key_exchange.h"
#include "tkm_keymat.h"
#include "tkm_types.h"
fail_unless(ng->nonce_gen.allocate_nonce(&ng->nonce_gen, 32, &nonce),
"Unable to allocate nonce");
- tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
- fail_if(!dh, "Unable to create DH");
+ tkm_key_exchange_t *ke = tkm_key_exchange_create(MODP_4096_BIT);
+ fail_if(!ke, "Unable to create KE");
/* Use the same pubvalue for both sides */
chunk_t pubvalue;
- ck_assert(dh->ke.get_public_key(&dh->ke, &pubvalue));
- ck_assert(dh->ke.set_public_key(&dh->ke, pubvalue));
+ ck_assert(ke->ke.get_public_key(&ke->ke, &pubvalue));
+ ck_assert(ke->ke.set_public_key(&ke->ke, pubvalue));
array_t *kes = NULL;
- array_insert_create(&kes, ARRAY_TAIL, dh);
+ array_insert_create(&kes, ARRAY_TAIL, ke);
fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
kes, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
"Key derivation failed");
ng->nonce_gen.destroy(&ng->nonce_gen);
proposal->destroy(proposal);
- dh->ke.destroy(&dh->ke);
+ ke->ke.destroy(&ke->ke);
ike_sa_id->destroy(ike_sa_id);
keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat);
chunk_free(&pubvalue);
START_TEST(test_derive_child_keys)
{
- tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
- fail_if(!dh, "Unable to create DH object");
+ tkm_key_exchange_t *ke = tkm_key_exchange_create(MODP_4096_BIT);
+ fail_if(!ke, "Unable to create DH object");
proposal_t *proposal = proposal_create_from_string(PROTO_ESP,
"aes256-sha512-modp4096");
fail_if(!proposal, "Unable to create proposal");
chunk_t nonce = chunk_from_chars("test chunk");
array_t *kes = NULL;
- array_insert_create(&kes, ARRAY_TAIL, dh);
+ array_insert_create(&kes, ARRAY_TAIL, ke);
fail_unless(keymat->keymat_v2.derive_child_keys(&keymat->keymat_v2, proposal,
kes, nonce, nonce, &encr_i,
&integ_i, &encr_r, &integ_r),
"nonce_r mismatch (encr_i)");
fail_if(info->is_encr_r,
"Flag is_encr_r set for encr_i");
- fail_if(info->dh_id != dh->get_id(dh),
- "DH context id mismatch (encr_i)");
+ fail_if(info->ke_ids.size != 1,
+ "KE context number mismatch (encr_i)");
+ fail_if(info->ke_ids.data[0] != ke->get_id(ke),
+ "KE context id mismatch (encr_i)");
chunk_free(&info->nonce_i);
chunk_free(&info->nonce_r);
"nonce_r mismatch (encr_r)");
fail_unless(info->is_encr_r,
"Flag is_encr_r set for encr_r");
- fail_if(info->dh_id != dh->get_id(dh),
- "DH context id mismatch (encr_i)");
+ fail_if(info->ke_ids.size != 1,
+ "KE context number mismatch (encr_i)");
+ fail_if(info->ke_ids.data[0] != ke->get_id(ke),
+ "KE context id mismatch (encr_i)");
chunk_free(&info->nonce_i);
chunk_free(&info->nonce_r);
proposal->destroy(proposal);
- dh->ke.destroy(&dh->ke);
+ ke->ke.destroy(&ke->ke);
keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat);
chunk_free(&encr_i);
chunk_free(&encr_r);
#include "tkm.h"
#include "tkm_nonceg.h"
-#include "tkm_diffie_hellman.h"
+#include "tkm_key_exchange.h"
#include "tkm_kernel_ipsec.h"
/* declare test suite constructors */
lib->plugins->add_static_features(lib->plugins, "tkm-tests", features,
countof(features), TRUE, NULL, NULL);
- lib->settings->set_int(lib->settings, "%s.dh_mapping.%d", 1,
+ lib->settings->set_int(lib->settings, "%s.ke_mapping.%d", 1,
lib->ns, MODP_3072_BIT);
- lib->settings->set_int(lib->settings, "%s.dh_mapping.%d", 2,
+ lib->settings->set_int(lib->settings, "%s.ke_mapping.%d", 2,
lib->ns, MODP_4096_BIT);
- register_dh_mapping();
+ register_ke_mapping();
plugin_loader_add_plugindirs(BUILDDIR "/src/libstrongswan/plugins",
PLUGINS);
result = FALSE;
}
- destroy_dh_mapping();
+ destroy_ke_mapping();
libcharon_deinit();
return result;
}
TEST_SUITE(make_chunk_map_tests)
TEST_SUITE(make_utility_tests)
TEST_SUITE_DEPEND(make_nonceg_tests, CUSTOM, "tkm")
-TEST_SUITE_DEPEND(make_diffie_hellman_tests, CUSTOM, "tkm")
+TEST_SUITE_DEPEND(make_key_exchange_tests, CUSTOM, "tkm")
TEST_SUITE_DEPEND(make_keymat_tests, CUSTOM, "tkm")
TEST_SUITE(make_kernel_sad_tests)
PKG = tkm-rpc
SRC = https://git.codelabs.ch/git/$(PKG).git
-REV = 85f725c0c938cc7f8a48ed86892d6b112b858b8b
+REV = v0.4
PREFIX = /usr/local/ada
PKG = tkm
SRC = https://git.codelabs.ch/git/$(PKG).git
-REV = e46eef9f0991ba2777dcde845c2e00b8df9c72f7
+REV = v0.3
export ADA_PROJECT_PATH=/usr/local/ada/lib/gnat
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
# /etc/strongswan.conf - strongSwan configuration file
charon-tkm {
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
moon::cat /tmp/tkm.log::Creating first new ESA context with ID 1 (Isa 1, Sp 1, Ea 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
-moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
+moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Ke_Id 1 #1 / 1, Nc_Loc_Id 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
moon::cat /tmp/tkm.log::Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 4, hard 60 \]::2
moon::cat /tmp/tkm.log::Resetting ESA context 1::YES
moon::cat /tmp/tkm.log::Deleting ESA \[ 1, 192.168.0.1 <=> 192.168.0.2, SPI_in.*, SPI_out.* \]::YES
charon-tkm {
# remove rekeyed inbound SA a bit quicker for the test scenario
delete_rekeyed_delay = 2
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}
moon::cat /tmp/tkm.log::Certificate chain of CC context 1 is valid::YES
moon::cat /tmp/tkm.log::Authentication of ISA context 1 successful::YES
moon::cat /tmp/tkm.log::Creating first new ESA context with ID 1 (Isa 1, Sp 1, Ea 1, Initiator TRUE, spi_loc.*, spi_rem.*)::YES
-moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Dh_Id 1, Nc_Loc_Id 1, Initiator FALSE, spi_loc.*, spi_rem.*)::YES
+moon::cat /tmp/tkm.log::Creating ESA context with ID 2 (Isa 1, Sp 1, Ea 1, Ke_Id 1 #1 / 1, Nc_Loc_Id 1, Initiator FALSE, spi_loc.*, spi_rem.*)::YES
moon::cat /tmp/tkm.log::Adding ESA \[ 1, 192.168.0.1 <-> 192.168.0.2, SPI_in.*, SPI_out.*, soft 30, hard 60 \]::2
moon::cat /tmp/tkm.log::Resetting ESA context 1::YES
moon::cat /tmp/tkm.log::Deleting ESA \[ 1, 192.168.0.1 <=> 192.168.0.2, SPI_in.*, SPI_out.* \]::YES
charon-tkm {
# remove rekeyed inbound SA a bit quicker for the test scenario
delete_rekeyed_delay = 2
- dh_mapping {
+ ke_mapping {
15 = 1
16 = 2
}