Let tkm_keymat_t extend keymat_v2_t
[strongswan.git] / src / charon-tkm / tests / keymat_tests.c
1 /*
2 * Copyright (C) 2012 Reto Buerki
3 * Copyright (C) 2012 Adrian-Ken Rueegsegger
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <check.h>
18 #include <daemon.h>
19 #include <hydra.h>
20 #include <config/proposal.h>
21 #include <encoding/payloads/ike_header.h>
22 #include <plugins/kernel_netlink/kernel_netlink_net.h>
23 #include <tkm/client.h>
24
25 #include "tkm.h"
26 #include "tkm_nonceg.h"
27 #include "tkm_diffie_hellman.h"
28 #include "tkm_keymat.h"
29 #include "tkm_kernel_ipsec.h"
30 #include "tkm_types.h"
31
32 START_TEST(test_derive_ike_keys)
33 {
34 fail_if(!library_init(NULL), "Unable to init library");
35 fail_if(!libhydra_init("tkm-tests"), "Unable to init libhydra");
36 fail_if(!libcharon_init("tkm-tests"), "Unable to init libcharon");
37
38 /* Register TKM specific plugins */
39 static plugin_feature_t features[] = {
40 PLUGIN_REGISTER(NONCE_GEN, tkm_nonceg_create),
41 PLUGIN_PROVIDE(NONCE_GEN),
42 PLUGIN_REGISTER(DH, tkm_diffie_hellman_create),
43 PLUGIN_PROVIDE(DH, MODP_3072_BIT),
44 PLUGIN_PROVIDE(DH, MODP_4096_BIT),
45 PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create),
46 PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
47 PLUGIN_DEPENDS(RNG, RNG_WEAK),
48 PLUGIN_CALLBACK(kernel_net_register, kernel_netlink_net_create),
49 PLUGIN_PROVIDE(CUSTOM, "kernel-net"),
50 };
51 lib->plugins->add_static_features(lib->plugins, "tkm-tests", features,
52 countof(features), TRUE);
53
54 fail_if(!charon->initialize(charon, PLUGINS), "Unable to init charon");
55
56 proposal_t *proposal = proposal_create_from_string(PROTO_IKE,
57 "aes256-sha512-modp4096");
58 fail_if(!proposal, "Unable to create proposal");
59 ike_sa_id_t *ike_sa_id = ike_sa_id_create(IKEV2_MAJOR_VERSION,
60 123912312312, 32312313122, TRUE);
61 fail_if(!ike_sa_id, "Unable to create IKE SA ID");
62
63 tkm_keymat_t *keymat = tkm_keymat_create(TRUE);
64 fail_if(!keymat, "Unable to create keymat");
65 fail_if(!keymat->get_isa_id(keymat), "Invalid ISA context id (0)");
66
67 chunk_t nonce;
68 tkm_nonceg_t *ng = tkm_nonceg_create();
69 fail_if(!ng, "Unable to create nonce generator");
70 fail_unless(ng->nonce_gen.allocate_nonce(&ng->nonce_gen, 32, &nonce),
71 "Unable to allocate nonce");
72 ng->nonce_gen.destroy(&ng->nonce_gen);
73
74 tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
75 fail_if(!dh, "Unable to create DH");
76
77 /* Use the same pubvalue for both sides */
78 chunk_t pubvalue;
79 dh->dh.get_my_public_value(&dh->dh, &pubvalue);
80 dh->dh.set_other_public_value(&dh->dh, pubvalue);
81
82 fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
83 &dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
84 "Key derivation failed");
85 chunk_free(&nonce);
86
87 aead_t * const aead = keymat->keymat_v2.keymat.get_aead(&keymat->keymat_v2.keymat, TRUE);
88 fail_if(!aead, "AEAD is NULL");
89
90 fail_if(aead->get_key_size(aead) != 96, "Key size mismatch %d",
91 aead->get_key_size(aead));
92 fail_if(aead->get_block_size(aead) != 16, "Block size mismatch %d",
93 aead->get_block_size(aead));
94
95 proposal->destroy(proposal);
96 dh->dh.destroy(&dh->dh);
97 ike_sa_id->destroy(ike_sa_id);
98 keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat);
99 chunk_free(&pubvalue);
100
101 libcharon_deinit();
102 libhydra_deinit();
103 library_deinit();
104 }
105 END_TEST
106
107 START_TEST(test_derive_child_keys)
108 {
109 fail_if(!library_init(NULL), "Unable to init library");
110 fail_if(!libhydra_init("tkm-tests"), "Unable to init libhydra");
111 fail_if(!libcharon_init("tkm-tests"), "Unable to init libcharon");
112
113 /* Register TKM specific plugins */
114 static plugin_feature_t features[] = {
115 PLUGIN_REGISTER(NONCE_GEN, tkm_nonceg_create),
116 PLUGIN_PROVIDE(NONCE_GEN),
117 PLUGIN_REGISTER(DH, tkm_diffie_hellman_create),
118 PLUGIN_PROVIDE(DH, MODP_3072_BIT),
119 PLUGIN_PROVIDE(DH, MODP_4096_BIT),
120 PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create),
121 PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
122 PLUGIN_DEPENDS(RNG, RNG_WEAK),
123 PLUGIN_CALLBACK(kernel_net_register, kernel_netlink_net_create),
124 PLUGIN_PROVIDE(CUSTOM, "kernel-net"),
125 };
126 lib->plugins->add_static_features(lib->plugins, "tkm-tests", features,
127 countof(features), TRUE);
128
129 fail_if(!charon->initialize(charon, PLUGINS), "Unable to init charon");
130
131 tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
132 fail_if(!dh, "Unable to create DH object");
133 proposal_t *proposal = proposal_create_from_string(PROTO_ESP,
134 "aes256-sha512-modp4096");
135 fail_if(!proposal, "Unable to create proposal");
136 proposal->set_spi(proposal, 42);
137
138 tkm_keymat_t *keymat = tkm_keymat_create(TRUE);
139 fail_if(!keymat, "Unable to create keymat");
140
141 chunk_t encr_i, encr_r, integ_i, integ_r;
142 chunk_t nonce = chunk_from_chars("test chunk");
143
144 fail_unless(keymat->keymat_v2.derive_child_keys(&keymat->keymat_v2, proposal,
145 (diffie_hellman_t *)dh,
146 nonce, nonce, &encr_i,
147 &integ_i, &encr_r, &integ_r),
148 "Child key derivation failed");
149
150 esa_info_t *info = (esa_info_t *)encr_i.ptr;
151 fail_if(!info, "encr_i does not contain esa information");
152 fail_if(info->isa_id != keymat->get_isa_id(keymat),
153 "Isa context id mismatch (encr_i)");
154 fail_if(info->spi_r != 42,
155 "SPI mismatch (encr_i)");
156 fail_unless(chunk_equals(info->nonce_i, nonce),
157 "nonce_i mismatch (encr_i)");
158 fail_unless(chunk_equals(info->nonce_r, nonce),
159 "nonce_r mismatch (encr_i)");
160 fail_if(info->is_encr_r,
161 "Flag is_encr_r set for encr_i");
162 fail_if(info->dh_id != dh->get_id(dh),
163 "DH context id mismatch (encr_i)");
164 chunk_free(&info->nonce_i);
165 chunk_free(&info->nonce_r);
166
167 info = (esa_info_t *)encr_r.ptr;
168 fail_if(!info, "encr_r does not contain esa information");
169 fail_if(info->isa_id != keymat->get_isa_id(keymat),
170 "Isa context id mismatch (encr_r)");
171 fail_if(info->spi_r != 42,
172 "SPI mismatch (encr_r)");
173 fail_unless(chunk_equals(info->nonce_i, nonce),
174 "nonce_i mismatch (encr_r)");
175 fail_unless(chunk_equals(info->nonce_r, nonce),
176 "nonce_r mismatch (encr_r)");
177 fail_unless(info->is_encr_r,
178 "Flag is_encr_r set for encr_r");
179 fail_if(info->dh_id != dh->get_id(dh),
180 "DH context id mismatch (encr_i)");
181 chunk_free(&info->nonce_i);
182 chunk_free(&info->nonce_r);
183
184 proposal->destroy(proposal);
185 dh->dh.destroy(&dh->dh);
186 keymat->keymat_v2.keymat.destroy(&keymat->keymat_v2.keymat);
187 chunk_free(&encr_i);
188 chunk_free(&encr_r);
189
190 libcharon_deinit();
191 libhydra_deinit();
192 library_deinit();
193 }
194 END_TEST
195
196 TCase *make_keymat_tests(void)
197 {
198 TCase *tc = tcase_create("Keymat tests");
199 tcase_add_test(tc, test_derive_ike_keys);
200 tcase_add_test(tc, test_derive_child_keys);
201
202 return tc;
203 }