summaryrefslogtreecommitdiff
path: root/src/charon-tkm/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon-tkm/tests')
-rw-r--r--src/charon-tkm/tests/.gitignore1
-rw-r--r--src/charon-tkm/tests/chunk_map_tests.c58
-rw-r--r--src/charon-tkm/tests/diffie_hellman_tests.c59
-rw-r--r--src/charon-tkm/tests/id_manager_tests.c150
-rw-r--r--src/charon-tkm/tests/kernel_sad_tests.c122
-rw-r--r--src/charon-tkm/tests/keymat_tests.c149
-rw-r--r--src/charon-tkm/tests/nonceg_tests.c93
-rw-r--r--src/charon-tkm/tests/test_runner.c84
-rw-r--r--src/charon-tkm/tests/test_runner.h30
-rw-r--r--src/charon-tkm/tests/utils_tests.c63
10 files changed, 809 insertions, 0 deletions
diff --git a/src/charon-tkm/tests/.gitignore b/src/charon-tkm/tests/.gitignore
new file mode 100644
index 000000000..35429f617
--- /dev/null
+++ b/src/charon-tkm/tests/.gitignore
@@ -0,0 +1 @@
+test_runner
diff --git a/src/charon-tkm/tests/chunk_map_tests.c b/src/charon-tkm/tests/chunk_map_tests.c
new file mode 100644
index 000000000..6deef9a80
--- /dev/null
+++ b/src/charon-tkm/tests/chunk_map_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 <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_chunk_map.h"
+
+START_TEST(test_chunk_map_creation)
+{
+ tkm_chunk_map_t *map = NULL;
+
+ map = tkm_chunk_map_create();
+ fail_if(map == NULL, "Error creating chunk map");
+
+ map->destroy(map);
+}
+END_TEST
+
+START_TEST(test_chunk_map_handling)
+{
+ tkm_chunk_map_t *map = NULL;
+ const int ref = 35;
+ chunk_t data = chunk_from_thing(ref);
+
+ map = tkm_chunk_map_create();
+ fail_if(map == NULL, "Error creating chunk map");
+
+ map->insert(map, &data, 24);
+ fail_if(map->get_id(map, &data) != 24, "Id mismatch");
+
+ fail_unless(map->remove(map, &data), "Unable to remove mapping");
+ fail_unless(!map->get_id(map, &data), "Error removing mapping");
+
+ map->destroy(map);
+}
+END_TEST
+
+TCase *make_chunk_map_tests(void)
+{
+ TCase *tc = tcase_create("Chunk map tests");
+ tcase_add_test(tc, test_chunk_map_creation);
+ tcase_add_test(tc, test_chunk_map_handling);
+
+ return tc;
+}
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 000000000..ffe99614d
--- /dev/null
+++ b/src/charon-tkm/tests/diffie_hellman_tests.c
@@ -0,0 +1,59 @@
+/*
+ * 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");
+ fail_if(!dh->get_id(dh), "Invalid context id (0)");
+
+ 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/id_manager_tests.c b/src/charon-tkm/tests/id_manager_tests.c
new file mode 100644
index 000000000..15522f118
--- /dev/null
+++ b/src/charon-tkm/tests/id_manager_tests.c
@@ -0,0 +1,150 @@
+/*
+ * 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_id_manager.h"
+
+static const tkm_limits_t limits = {125, 100, 55, 30, 200, 42};
+
+START_TEST(test_id_mgr_creation)
+{
+ tkm_id_manager_t *idmgr = NULL;
+
+ idmgr = tkm_id_manager_create(limits);
+ fail_if(idmgr == NULL, "Error creating tkm id manager");
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_acquire_id)
+{
+ int i, id = 0;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ for (i = 0; i < TKM_CTX_MAX; i++)
+ {
+ id = idmgr->acquire_id(idmgr, i);
+ fail_unless(id > 0, "Error acquiring id of context kind %d", i);
+
+ /* Reset test variable */
+ id = 0;
+ }
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_acquire_id_invalid_kind)
+{
+ int id = 0;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ id = idmgr->acquire_id(idmgr, TKM_CTX_MAX);
+ fail_unless(id == 0, "Acquired id for invalid context kind %d", TKM_CTX_MAX);
+
+ /* Reset test variable */
+ id = 0;
+
+ id = idmgr->acquire_id(idmgr, -1);
+ fail_unless(id == 0, "Acquired id for invalid context kind %d", -1);
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_acquire_id_same)
+{
+ int id1 = 0, id2 = 0;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ id1 = idmgr->acquire_id(idmgr, TKM_CTX_NONCE);
+ fail_unless(id1 > 0, "Unable to acquire first id");
+
+ /* Acquire another id, must be different than first */
+ id2 = idmgr->acquire_id(idmgr, TKM_CTX_NONCE);
+ fail_unless(id2 > 0, "Unable to acquire second id");
+ fail_unless(id1 != id2, "Same id received twice");
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_release_id)
+{
+ int i, id = 0;
+ bool released = false;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ for (i = 0; i < TKM_CTX_MAX; i++)
+ {
+ id = idmgr->acquire_id(idmgr, i);
+ released = idmgr->release_id(idmgr, i, id);
+
+ fail_unless(released, "Error releasing id of context kind %d", i);
+
+ /* Reset released variable */
+ released = FALSE;
+ }
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_release_id_invalid_kind)
+{
+ bool released = TRUE;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ released = idmgr->release_id(idmgr, TKM_CTX_MAX, 1);
+ fail_if(released, "Released id for invalid context kind %d", TKM_CTX_MAX);
+
+ /* Reset test variable */
+ released = TRUE;
+
+ released = idmgr->release_id(idmgr, -1, 1);
+ fail_if(released, "Released id for invalid context kind %d", -1);
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+START_TEST(test_release_id_nonexistent)
+{
+ bool released = FALSE;
+ tkm_id_manager_t *idmgr = tkm_id_manager_create(limits);
+
+ released = idmgr->release_id(idmgr, TKM_CTX_NONCE, 1);
+ fail_unless(released, "Release of nonexistent id failed");
+
+ idmgr->destroy(idmgr);
+}
+END_TEST
+
+TCase *make_id_manager_tests(void)
+{
+ TCase *tc = tcase_create("Context id manager tests");
+ tcase_add_test(tc, test_id_mgr_creation);
+ tcase_add_test(tc, test_acquire_id);
+ tcase_add_test(tc, test_acquire_id_invalid_kind);
+ tcase_add_test(tc, test_acquire_id_same);
+ tcase_add_test(tc, test_release_id);
+ tcase_add_test(tc, test_release_id_invalid_kind);
+ tcase_add_test(tc, test_release_id_nonexistent);
+
+ return tc;
+}
diff --git a/src/charon-tkm/tests/kernel_sad_tests.c b/src/charon-tkm/tests/kernel_sad_tests.c
new file mode 100644
index 000000000..11785602d
--- /dev/null
+++ b/src/charon-tkm/tests/kernel_sad_tests.c
@@ -0,0 +1,122 @@
+/*
+ * 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_kernel_sad.h"
+
+START_TEST(test_sad_creation)
+{
+ tkm_kernel_sad_t *sad = NULL;
+
+ sad = tkm_kernel_sad_create();
+ fail_if(!sad, "Error creating tkm kernel SAD");
+
+ sad->destroy(sad);
+}
+END_TEST
+
+START_TEST(test_insert)
+{
+ host_t *addr = host_create_from_string("127.0.0.1", 1024);
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+
+ fail_unless(sad->insert(sad, 1, addr, addr, 42, 50),
+ "Error inserting SAD entry");
+
+ sad->destroy(sad);
+ addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_insert_duplicate)
+{
+ host_t *addr = host_create_from_string("127.0.0.1", 1024);
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+
+ fail_unless(sad->insert(sad, 1, addr, addr, 42, 50),
+ "Error inserting SAD entry");
+ fail_if(sad->insert(sad, 1, addr, addr, 42, 50),
+ "Expected error inserting duplicate entry");
+
+ sad->destroy(sad);
+ addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_get_esa_id)
+{
+ host_t *addr = host_create_from_string("127.0.0.1", 1024);
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+ fail_unless(sad->insert(sad, 23, addr, addr, 42, 50),
+ "Error inserting SAD entry");
+ fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
+ "Error getting esa id");
+ sad->destroy(sad);
+ addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_get_esa_id_nonexistent)
+{
+ host_t *addr = host_create_from_string("127.0.0.1", 1024);
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+ fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 0,
+ "Got esa id for nonexistent SAD entry");
+ sad->destroy(sad);
+ addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_remove)
+{
+ host_t *addr = host_create_from_string("127.0.0.1", 1024);
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+ fail_unless(sad->insert(sad, 23, addr, addr, 42, 50),
+ "Error inserting SAD entry");
+ fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
+ "Error getting esa id");
+ fail_unless(sad->remove(sad, 23),
+ "Error removing SAD entry");
+ fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 0,
+ "Got esa id for removed SAD entry");
+ sad->destroy(sad);
+ addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_remove_nonexistent)
+{
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+ fail_if(sad->remove(sad, 1),
+ "Expected error removing nonexistent SAD entry");
+ sad->destroy(sad);
+}
+END_TEST
+
+TCase *make_kernel_sad_tests(void)
+{
+ TCase *tc = tcase_create("Kernel SAD tests");
+ tcase_add_test(tc, test_sad_creation);
+ tcase_add_test(tc, test_insert);
+ tcase_add_test(tc, test_insert_duplicate);
+ tcase_add_test(tc, test_get_esa_id);
+ tcase_add_test(tc, test_get_esa_id_nonexistent);
+ tcase_add_test(tc, test_remove);
+ tcase_add_test(tc, test_remove_nonexistent);
+
+ return tc;
+}
diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c
new file mode 100644
index 000000000..2a7525d4e
--- /dev/null
+++ b/src/charon-tkm/tests/keymat_tests.c
@@ -0,0 +1,149 @@
+/*
+ * 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 <daemon.h>
+#include <hydra.h>
+#include <config/proposal.h>
+#include <encoding/payloads/ike_header.h>
+#include <tkm/client.h>
+
+#include "tkm.h"
+#include "tkm_nonceg.h"
+#include "tkm_diffie_hellman.h"
+#include "tkm_keymat.h"
+#include "tkm_types.h"
+
+START_TEST(test_derive_ike_keys)
+{
+ proposal_t *proposal = proposal_create_from_string(PROTO_IKE,
+ "aes256-sha512-modp4096");
+ fail_if(!proposal, "Unable to create proposal");
+ ike_sa_id_t *ike_sa_id = ike_sa_id_create(IKEV2_MAJOR_VERSION,
+ 123912312312, 32312313122, TRUE);
+ fail_if(!ike_sa_id, "Unable to create IKE SA ID");
+
+ tkm_keymat_t *keymat = tkm_keymat_create(TRUE);
+ fail_if(!keymat, "Unable to create keymat");
+ fail_if(!keymat->get_isa_id(keymat), "Invalid ISA context id (0)");
+
+ chunk_t nonce;
+ tkm_nonceg_t *ng = tkm_nonceg_create();
+ fail_if(!ng, "Unable to create nonce generator");
+ fail_unless(ng->nonce_gen.allocate_nonce(&ng->nonce_gen, 32, &nonce),
+ "Unable to allocate nonce");
+ ng->nonce_gen.destroy(&ng->nonce_gen);
+
+ tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
+ fail_if(!dh, "Unable to create DH");
+
+ /* Use the same pubvalue for both sides */
+ chunk_t pubvalue;
+ dh->dh.get_my_public_value(&dh->dh, &pubvalue);
+ dh->dh.set_other_public_value(&dh->dh, pubvalue);
+
+ fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
+ &dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
+ "Key derivation failed");
+ chunk_free(&nonce);
+
+ aead_t * const aead = keymat->keymat_v2.keymat.get_aead(&keymat->keymat_v2.keymat, TRUE);
+ fail_if(!aead, "AEAD is NULL");
+
+ fail_if(aead->get_key_size(aead) != 96, "Key size mismatch %d",
+ aead->get_key_size(aead));
+ fail_if(aead->get_block_size(aead) != 16, "Block size mismatch %d",
+ aead->get_block_size(aead));
+
+ proposal->destroy(proposal);
+ dh->dh.destroy(&dh->dh);
+ ike_sa_id->destroy(ike_sa_id);
+ keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat);
+ chunk_free(&pubvalue);
+}
+END_TEST
+
+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");
+ proposal_t *proposal = proposal_create_from_string(PROTO_ESP,
+ "aes256-sha512-modp4096");
+ fail_if(!proposal, "Unable to create proposal");
+ proposal->set_spi(proposal, 42);
+
+ tkm_keymat_t *keymat = tkm_keymat_create(TRUE);
+ fail_if(!keymat, "Unable to create keymat");
+
+ chunk_t encr_i, encr_r, integ_i, integ_r;
+ chunk_t nonce = chunk_from_chars("test chunk");
+
+ fail_unless(keymat->keymat_v2.derive_child_keys(&keymat->keymat_v2, proposal,
+ (diffie_hellman_t *)dh,
+ nonce, nonce, &encr_i,
+ &integ_i, &encr_r, &integ_r),
+ "Child key derivation failed");
+
+ esa_info_t *info = (esa_info_t *)encr_i.ptr;
+ fail_if(!info, "encr_i does not contain esa information");
+ fail_if(info->isa_id != keymat->get_isa_id(keymat),
+ "Isa context id mismatch (encr_i)");
+ fail_if(info->spi_r != 42,
+ "SPI mismatch (encr_i)");
+ fail_unless(chunk_equals(info->nonce_i, nonce),
+ "nonce_i mismatch (encr_i)");
+ fail_unless(chunk_equals(info->nonce_r, nonce),
+ "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)");
+ chunk_free(&info->nonce_i);
+ chunk_free(&info->nonce_r);
+
+ info = (esa_info_t *)encr_r.ptr;
+ fail_if(!info, "encr_r does not contain esa information");
+ fail_if(info->isa_id != keymat->get_isa_id(keymat),
+ "Isa context id mismatch (encr_r)");
+ fail_if(info->spi_r != 42,
+ "SPI mismatch (encr_r)");
+ fail_unless(chunk_equals(info->nonce_i, nonce),
+ "nonce_i mismatch (encr_r)");
+ fail_unless(chunk_equals(info->nonce_r, nonce),
+ "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)");
+ chunk_free(&info->nonce_i);
+ chunk_free(&info->nonce_r);
+
+ proposal->destroy(proposal);
+ dh->dh.destroy(&dh->dh);
+ keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat);
+ chunk_free(&encr_i);
+ chunk_free(&encr_r);
+}
+END_TEST
+
+TCase *make_keymat_tests(void)
+{
+ TCase *tc = tcase_create("Keymat tests");
+ tcase_add_test(tc, test_derive_ike_keys);
+ tcase_add_test(tc, test_derive_child_keys);
+
+ return tc;
+}
diff --git a/src/charon-tkm/tests/nonceg_tests.c b/src/charon-tkm/tests/nonceg_tests.c
new file mode 100644
index 000000000..3a1effab8
--- /dev/null
+++ b/src/charon-tkm/tests/nonceg_tests.c
@@ -0,0 +1,93 @@
+/*
+ * 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/client.h>
+
+#include "tkm.h"
+#include "tkm_nonceg.h"
+
+START_TEST(test_nonceg_creation)
+{
+ tkm_nonceg_t *ng = NULL;
+
+ ng = tkm_nonceg_create();
+ fail_if(ng == NULL, "Error creating tkm nonce generator");
+ fail_if(ng->get_id(ng) == 0, "Invalid context id (0)");
+
+ ng->nonce_gen.destroy(&ng->nonce_gen);
+}
+END_TEST
+
+START_TEST(test_nonceg_allocate_nonce)
+{
+ tkm_nonceg_t *ng = tkm_nonceg_create();
+
+ const size_t length = 256;
+ u_int8_t zero[length];
+ memset(zero, 0, length);
+
+ chunk_t nonce;
+ const bool got_nonce = ng->nonce_gen.allocate_nonce(&ng->nonce_gen,
+ length, &nonce);
+
+ fail_unless(got_nonce, "Call to allocate_nonce failed");
+ fail_unless(nonce.len = length, "Allocated nonce length mismatch");
+ fail_if(memcmp(nonce.ptr, zero, length) == 0, "Unable to allocate nonce");
+
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, 1);
+ ike_nc_reset(1);
+
+ chunk_free(&nonce);
+ ng->nonce_gen.destroy(&ng->nonce_gen);
+}
+END_TEST
+
+START_TEST(test_nonceg_get_nonce)
+{
+ tkm_nonceg_t *ng = tkm_nonceg_create();
+
+ const size_t length = 128;
+ u_int8_t zero[length];
+ memset(zero, 0, length);
+
+ u_int8_t *buf = malloc(length + 1);
+ memset(buf, 0, length);
+ /* set end marker */
+ buf[length] = 255;
+
+ const bool got_nonce = ng->nonce_gen.get_nonce(&ng->nonce_gen, length, buf);
+ fail_unless(got_nonce, "Call to get_nonce failed");
+ fail_if(memcmp(buf, zero, length) == 0, "Unable to get nonce");
+ fail_if(buf[length] != 255, "End marker not found");
+
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, 1);
+ ike_nc_reset(1);
+
+ free(buf);
+ ng->nonce_gen.destroy(&ng->nonce_gen);
+}
+END_TEST
+
+TCase *make_nonceg_tests(void)
+{
+ TCase *tc = tcase_create("Nonce generator tests");
+ tcase_add_test(tc, test_nonceg_creation);
+ tcase_add_test(tc, test_nonceg_allocate_nonce);
+ tcase_add_test(tc, test_nonceg_get_nonce);
+
+ return tc;
+}
diff --git a/src/charon-tkm/tests/test_runner.c b/src/charon-tkm/tests/test_runner.c
new file mode 100644
index 000000000..5ae032935
--- /dev/null
+++ b/src/charon-tkm/tests/test_runner.c
@@ -0,0 +1,84 @@
+/*
+ * 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 <library.h>
+#include <hydra.h>
+#include <daemon.h>
+
+#include "tkm.h"
+#include "tkm_nonceg.h"
+#include "tkm_diffie_hellman.h"
+#include "tkm_kernel_ipsec.h"
+#include "test_runner.h"
+
+int main(void)
+{
+ library_init(NULL);
+ libhydra_init("test_runner");
+ libcharon_init("test_runner");
+
+ lib->settings->set_int(lib->settings, "test_runner.filelog.stdout.default",
+ 1);
+ charon->load_loggers(charon, NULL, FALSE);
+
+ /* Register TKM specific plugins */
+ static plugin_feature_t features[] = {
+ PLUGIN_REGISTER(NONCE_GEN, tkm_nonceg_create),
+ PLUGIN_PROVIDE(NONCE_GEN),
+ PLUGIN_REGISTER(DH, tkm_diffie_hellman_create),
+ PLUGIN_PROVIDE(DH, MODP_3072_BIT),
+ PLUGIN_PROVIDE(DH, MODP_4096_BIT),
+ PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create),
+ PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
+ };
+ lib->plugins->add_static_features(lib->plugins, "tkm-tests", features,
+ countof(features), TRUE);
+
+ if (!charon->initialize(charon, PLUGINS))
+ {
+ fprintf(stderr, "Unable to init charon");
+ return EXIT_FAILURE;
+ }
+
+ if (!tkm_init())
+ {
+ fprintf(stderr, "Could not connect to TKM, aborting tests\n");
+ return EXIT_FAILURE;
+ }
+
+ int number_failed;
+ Suite *s = suite_create("TKM tests");
+ suite_add_tcase(s, make_id_manager_tests());
+ suite_add_tcase(s, make_chunk_map_tests());
+ suite_add_tcase(s, make_utility_tests());
+ suite_add_tcase(s, make_nonceg_tests());
+ suite_add_tcase(s, make_diffie_hellman_tests());
+ suite_add_tcase(s, make_keymat_tests());
+ suite_add_tcase(s, make_kernel_sad_tests());
+
+ SRunner *sr = srunner_create(s);
+
+ srunner_run_all(sr, CK_NORMAL);
+ number_failed = srunner_ntests_failed(sr);
+
+ tkm_deinit();
+ libcharon_deinit();
+ libhydra_deinit();
+ library_deinit();
+ srunner_free(sr);
+
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/charon-tkm/tests/test_runner.h b/src/charon-tkm/tests/test_runner.h
new file mode 100644
index 000000000..236a7f2a6
--- /dev/null
+++ b/src/charon-tkm/tests/test_runner.h
@@ -0,0 +1,30 @@
+/*
+ * 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 TEST_RUNNER_H_
+#define TEST_RUNNER_H_
+
+#include <check.h>
+
+TCase *make_id_manager_tests(void);
+TCase *make_chunk_map_tests(void);
+TCase *make_utility_tests(void);
+TCase *make_nonceg_tests(void);
+TCase *make_diffie_hellman_tests(void);
+TCase *make_keymat_tests(void);
+TCase *make_kernel_sad_tests(void);
+
+#endif /** TEST_RUNNER_H_ */
diff --git a/src/charon-tkm/tests/utils_tests.c b/src/charon-tkm/tests/utils_tests.c
new file mode 100644
index 000000000..b3ead7633
--- /dev/null
+++ b/src/charon-tkm/tests/utils_tests.c
@@ -0,0 +1,63 @@
+/*
+ * 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/types.h>
+
+#include "tkm_utils.h"
+
+START_TEST(test_sequence_to_chunk)
+{
+ key_type key = {5, {0, 1, 2, 3, 4}};
+ chunk_t chunk = chunk_empty;
+
+ sequence_to_chunk(key.data, key.size, &chunk);
+ fail_if(chunk.len != key.size, "Chunk size mismatch");
+
+ uint32_t i;
+ for (i = 0; i < key.size; i++)
+ {
+ fail_if(chunk.ptr[i] != i, "Data mismatch");
+ }
+ chunk_free(&chunk);
+}
+END_TEST
+
+START_TEST(test_chunk_to_sequence)
+{
+ chunk_t chunk = chunk_from_thing("ABCDEFGH");
+ key_type key;
+
+ chunk_to_sequence(&chunk, &key, sizeof(key_type));
+ fail_if(key.size != chunk.len, "Seq size mismatch");
+
+ uint32_t i;
+ for (i = 0; i < key.size - 1; i++)
+ {
+ fail_if(key.data[i] != 65 + i, "Data mismatch (1)");
+ }
+ fail_if(key.data[key.size - 1] != 0, "Data mismatch (2)");
+}
+END_TEST
+
+TCase *make_utility_tests(void)
+{
+ TCase *tc = tcase_create("Utility tests");
+ tcase_add_test(tc, test_sequence_to_chunk);
+ tcase_add_test(tc, test_chunk_to_sequence);
+
+ return tc;
+}