diff options
Diffstat (limited to 'src/charon-tkm/src/tkm/tkm_diffie_hellman.c')
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_diffie_hellman.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c new file mode 100644 index 000000000..19f57de01 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c @@ -0,0 +1,140 @@ +/* + * Copyrigth (C) 2012 Reto Buerki + * Copyright (C) 2012 Adrian-Ken Rueegsegger + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <tkm/client.h> +#include <tkm/constants.h> + +#include "tkm.h" +#include "tkm_utils.h" +#include "tkm_diffie_hellman.h" + +#include <utils/debug.h> + +typedef struct private_tkm_diffie_hellman_t private_tkm_diffie_hellman_t; + +/** + * Private data of a tkm_diffie_hellman_t object. + */ +struct private_tkm_diffie_hellman_t { + + /** + * Public tkm_diffie_hellman_t interface. + */ + tkm_diffie_hellman_t public; + + /** + * Diffie Hellman group number. + */ + u_int16_t group; + + /** + * Diffie Hellman public value. + */ + dh_pubvalue_type pubvalue; + + /** + * Context id. + */ + dh_id_type context_id; + +}; + +METHOD(diffie_hellman_t, get_my_public_value, void, + private_tkm_diffie_hellman_t *this, chunk_t *value) +{ + sequence_to_chunk(this->pubvalue.data, this->pubvalue.size, value); +} + +METHOD(diffie_hellman_t, get_shared_secret, status_t, + private_tkm_diffie_hellman_t *this, chunk_t *secret) +{ + *secret = chunk_empty; + return SUCCESS; +} + + +METHOD(diffie_hellman_t, set_other_public_value, void, + private_tkm_diffie_hellman_t *this, chunk_t value) +{ + // TODO: unvoid this function + + dh_pubvalue_type othervalue; + othervalue.size = value.len; + memcpy(&othervalue.data, value.ptr, value.len); + + ike_dh_generate_key(this->context_id, othervalue); +} + +METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, + private_tkm_diffie_hellman_t *this) +{ + return this->group; +} + +METHOD(diffie_hellman_t, destroy, void, + private_tkm_diffie_hellman_t *this) +{ + if (ike_dh_reset(this->context_id) != TKM_OK) + { + DBG1(DBG_LIB, "failed to reset DH context %d", this->context_id); + } + + tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_DH, this->context_id); + free(this); +} + +METHOD(tkm_diffie_hellman_t, get_id, dh_id_type, + private_tkm_diffie_hellman_t *this) +{ + return this->context_id; +} + +/* + * Described in header. + */ +tkm_diffie_hellman_t *tkm_diffie_hellman_create(diffie_hellman_group_t group) +{ + private_tkm_diffie_hellman_t *this; + + INIT(this, + .public = { + .dh = { + .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, + .destroy = _destroy, + }, + .get_id = _get_id, + }, + .group = group, + .context_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_DH), + ); + + if (!this->context_id) + { + free(this); + return NULL; + } + + if (ike_dh_create(this->context_id, group, &this->pubvalue) != TKM_OK) + { + free(this); + return NULL; + } + + return &this->public; +} |