2 * Copyright (C) 2012 Reto Buerki
3 * Copyright (C) 2012 Adrian-Ken Rueegsegger
4 * Hochschule fuer Technik Rapperswil
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>.
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
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>
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"
32 START_TEST(test_derive_ike_keys
)
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");
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"),
51 lib
->plugins
->add_static_features(lib
->plugins
, "tkm-tests", features
,
52 countof(features
), TRUE
);
54 fail_if(!charon
->initialize(charon
, PLUGINS
), "Unable to init charon");
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");
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)");
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
);
74 tkm_diffie_hellman_t
*dh
= tkm_diffie_hellman_create(MODP_4096_BIT
);
75 fail_if(!dh
, "Unable to create DH");
77 /* Use the same pubvalue for both sides */
79 dh
->dh
.get_my_public_value(&dh
->dh
, &pubvalue
);
80 dh
->dh
.set_other_public_value(&dh
->dh
, pubvalue
);
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");
87 aead_t
* const aead
= keymat
->keymat_v2
.keymat
.get_aead(&keymat
->keymat_v2
.keymat
, TRUE
);
88 fail_if(!aead
, "AEAD is NULL");
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
));
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
);
107 START_TEST(test_derive_child_keys
)
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");
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"),
126 lib
->plugins
->add_static_features(lib
->plugins
, "tkm-tests", features
,
127 countof(features
), TRUE
);
129 fail_if(!charon
->initialize(charon
, PLUGINS
), "Unable to init charon");
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);
138 tkm_keymat_t
*keymat
= tkm_keymat_create(TRUE
);
139 fail_if(!keymat
, "Unable to create keymat");
141 chunk_t encr_i
, encr_r
, integ_i
, integ_r
;
142 chunk_t nonce
= chunk_from_chars("test chunk");
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");
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
);
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
);
184 proposal
->destroy(proposal
);
185 dh
->dh
.destroy(&dh
->dh
);
186 keymat
->keymat_v2
.keymat
.destroy(&keymat
->keymat_v2
.keymat
);
196 TCase
*make_keymat_tests(void)
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
);