From f3cd7f50dea0bfc9806322eeacfae6b19a350272 Mon Sep 17 00:00:00 2001 From: Reto Buerki Date: Tue, 24 Jul 2012 10:40:26 +0200 Subject: [PATCH] Add initial TKM Diffie-Hellman implementation The tkm_diffie_hellman_t plugin acquires a DH context from the Trusted Key Manager and uses it to get a DH public value and the calculated shared secret. Proper context handling is still missing though, the plugin currently uses context ID 1. The get_shared_secret function will be removed as soon as the TKM specific keymat is ready. --- src/charon-tkm/Makefile.am | 1 - src/charon-tkm/src/charon-tkm.c | 6 +- src/charon-tkm/src/tkm/tkm_diffie_hellman.c | 126 ++++++++++++++++++++++++++++ src/charon-tkm/src/tkm/tkm_diffie_hellman.h | 43 ++++++++++ src/charon-tkm/tests/diffie_hellman_tests.c | 58 +++++++++++++ src/charon-tkm/tests/test_runner.c | 1 + src/charon-tkm/tests/test_runner.h | 1 + 7 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 src/charon-tkm/src/tkm/tkm_diffie_hellman.c create mode 100644 src/charon-tkm/src/tkm/tkm_diffie_hellman.h create mode 100644 src/charon-tkm/tests/diffie_hellman_tests.c diff --git a/src/charon-tkm/Makefile.am b/src/charon-tkm/Makefile.am index 94216ca..1b5dfdf 100644 --- a/src/charon-tkm/Makefile.am +++ b/src/charon-tkm/Makefile.am @@ -24,7 +24,6 @@ BUILD_OPTS = \ PLUGINS = \ aes \ constraints \ - gmp \ hmac \ kernel-netlink \ pem \ diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index c9c27ba..bf8745a 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -34,6 +34,7 @@ #include "tkm.h" #include "tkm_nonceg.h" +#include "tkm_diffie_hellman.h" /** * PID file, in which charon-tkm stores its process id @@ -271,7 +272,10 @@ int main(int argc, char *argv[]) /* register TKM specific plugins */ static plugin_feature_t features[] = { PLUGIN_REGISTER(NONCE_GEN, tkm_nonceg_create), - PLUGIN_PROVIDE(NONCE_GEN) + PLUGIN_PROVIDE(NONCE_GEN), + PLUGIN_REGISTER(DH, tkm_diffie_hellman_create), + PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_PROVIDE(DH, MODP_4096_BIT), }; lib->plugins->add_static_features(lib->plugins, "tkm-backend", features, countof(features), TRUE); 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 0000000..fa5b0c5 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c @@ -0,0 +1,126 @@ +/* + * 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 . + * + * 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 +#include + +#include "tkm_diffie_hellman.h" + +#include + +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; +}; + +METHOD(diffie_hellman_t, get_my_public_value, void, + private_tkm_diffie_hellman_t *this, chunk_t *value) +{ + *value = chunk_alloc(this->pubvalue.size); + memcpy(value->ptr, &this->pubvalue.data, value->len); +} + +METHOD(diffie_hellman_t, get_shared_secret, status_t, + private_tkm_diffie_hellman_t *this, chunk_t *secret) +{ + dh_key_type shared_secret; + if (ike_dh_get_shared_secret(1, &shared_secret) != TKM_OK) + { + return FAILED; + } + + *secret = chunk_alloc(shared_secret.size); + memcpy(secret->ptr, &shared_secret.data, secret->len); + 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(1, 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) +{ + // TODO: unvoid this function + + free(this); + if (ike_dh_reset(1) != TKM_OK) + { + DBG1(DBG_LIB, "resetting DH context 1 failed"); + } +} + +/* + * 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, + }, + }, + ); + + if (ike_dh_create(1, group, &this->pubvalue) != TKM_OK) + { + free(this); + return NULL; + } + + this->group = group; + + return &this->public; +} diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.h b/src/charon-tkm/src/tkm/tkm_diffie_hellman.h new file mode 100644 index 0000000..25d1967 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.h @@ -0,0 +1,43 @@ +/* + * Copyright (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 . + * + * 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. + */ + +#ifndef TKM_DIFFIE_HELLMAN_H_ +#define TKM_DIFFIE_HELLMAN_H_ + +typedef struct tkm_diffie_hellman_t tkm_diffie_hellman_t; + +#include + +/** + * diffie_hellman_t implementation using the trusted key manager. + */ +struct tkm_diffie_hellman_t { + + /** + * Implements diffie_hellman_t interface. + */ + diffie_hellman_t dh; +}; + +/** + * Creates a new tkm_diffie_hellman_t object. + * + * @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); + +#endif /** TKM_DIFFIE_HELLMAN_H_ */ diff --git a/src/charon-tkm/tests/diffie_hellman_tests.c b/src/charon-tkm/tests/diffie_hellman_tests.c new file mode 100644 index 0000000..c2e905e --- /dev/null +++ b/src/charon-tkm/tests/diffie_hellman_tests.c @@ -0,0 +1,58 @@ +/* + * Copyright (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 . + * + * 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 + +#include "tkm_diffie_hellman.h" + +START_TEST(test_dh_creation) +{ + tkm_diffie_hellman_t *dh = NULL; + + dh = tkm_diffie_hellman_create(MODP_768_BIT); + fail_if(dh, "MODP_768 created"); + + dh = tkm_diffie_hellman_create(MODP_4096_BIT); + fail_if(!dh, "MODP_4096 not created"); + + dh->dh.destroy(&dh->dh); +} +END_TEST + +START_TEST(test_dh_get_my_pubvalue) +{ + tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT); + fail_if(!dh, "Unable to create DH"); + + chunk_t value; + dh->dh.get_my_public_value(&dh->dh, &value); + dh->dh.destroy(&dh->dh); + + fail_if(value.ptr == NULL, "Pubvalue is NULL"); + fail_if(value.len != 512, "Pubvalue size mismatch"); + + chunk_free(&value); +} +END_TEST + +TCase *make_diffie_hellman_tests(void) +{ + TCase *tc = tcase_create("Diffie-Hellman tests"); + tcase_add_test(tc, test_dh_creation); + tcase_add_test(tc, test_dh_get_my_pubvalue); + + return tc; +} diff --git a/src/charon-tkm/tests/test_runner.c b/src/charon-tkm/tests/test_runner.c index c16ad35..5c795f8 100644 --- a/src/charon-tkm/tests/test_runner.c +++ b/src/charon-tkm/tests/test_runner.c @@ -29,6 +29,7 @@ int main(void) Suite *s = suite_create("TKM tests"); suite_add_tcase(s, make_id_manager_tests()); suite_add_tcase(s, make_nonceg_tests()); + suite_add_tcase(s, make_diffie_hellman_tests()); SRunner *sr = srunner_create(s); diff --git a/src/charon-tkm/tests/test_runner.h b/src/charon-tkm/tests/test_runner.h index 3d15fb9..1de47d5 100644 --- a/src/charon-tkm/tests/test_runner.h +++ b/src/charon-tkm/tests/test_runner.h @@ -21,5 +21,6 @@ TCase *make_id_manager_tests(void); TCase *make_nonceg_tests(void); +TCase *make_diffie_hellman_tests(void); #endif /** TEST_RUNNER_H_ */ -- 2.7.4