Add initial TKM Diffie-Hellman implementation
authorReto Buerki <reet@codelabs.ch>
Tue, 24 Jul 2012 08:40:26 +0000 (10:40 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:45 +0000 (15:23 +0100)
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
src/charon-tkm/src/charon-tkm.c
src/charon-tkm/src/tkm/tkm_diffie_hellman.c [new file with mode: 0644]
src/charon-tkm/src/tkm/tkm_diffie_hellman.h [new file with mode: 0644]
src/charon-tkm/tests/diffie_hellman_tests.c [new file with mode: 0644]
src/charon-tkm/tests/test_runner.c
src/charon-tkm/tests/test_runner.h

index 94216ca..1b5dfdf 100644 (file)
@@ -24,7 +24,6 @@ BUILD_OPTS = \
 PLUGINS = \
        aes \
        constraints \
-       gmp \
        hmac \
        kernel-netlink \
        pem \
index c9c27ba..bf8745a 100644 (file)
@@ -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 (file)
index 0000000..fa5b0c5
--- /dev/null
@@ -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 <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_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;
+};
+
+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 (file)
index 0000000..25d1967
--- /dev/null
@@ -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 <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.
+ */
+
+#ifndef TKM_DIFFIE_HELLMAN_H_
+#define TKM_DIFFIE_HELLMAN_H_
+
+typedef struct tkm_diffie_hellman_t tkm_diffie_hellman_t;
+
+#include <library.h>
+
+/**
+ * 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 (file)
index 0000000..c2e905e
--- /dev/null
@@ -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 <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 <check.h>
+
+#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;
+}
index c16ad35..5c795f8 100644 (file)
@@ -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);
 
index 3d15fb9..1de47d5 100644 (file)
@@ -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_ */