Implement CHILD SA key derivation using TKM
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>
Mon, 10 Sep 2012 08:43:05 +0000 (10:43 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:47 +0000 (15:23 +0100)
ESP SAs are created when adding CHILD SAs via the kernel ipsec
interface.

The encr_i key is used to transfer the context id of the parent IKE SA
from the keymat to the TKM kernel ipsec interface.

src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
src/charon-tkm/src/tkm/tkm_keymat.c
src/charon-tkm/src/tkm/tkm_types.h [new file with mode: 0644]

index 7036b89..421d2f3 100644 (file)
 
 #include <utils/debug.h>
 #include <plugins/kernel_netlink/kernel_netlink_ipsec.h>
+#include <tkm/constants.h>
+#include <tkm/client.h>
 
+#include "tkm_types.h"
+#include "tkm_keymat.h"
 #include "tkm_kernel_ipsec.h"
 
 typedef struct private_tkm_kernel_ipsec_t private_tkm_kernel_ipsec_t;
@@ -36,6 +40,11 @@ struct private_tkm_kernel_ipsec_t {
         */
        kernel_netlink_ipsec_t *proxy;
 
+       /**
+        * Local CHILD SA SPI.
+        */
+       uint32_t esp_spi_loc;
+
 };
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
@@ -62,11 +71,30 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
        u_int16_t cpi, bool encap, bool esn, bool inbound,
        traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
 {
-       DBG1(DBG_KNL, "adding child SA with SPI %.8x and reqid {%u}", ntohl(spi),
-                reqid);
+       if (inbound && this->esp_spi_loc == 0)
+       {
+               DBG1(DBG_KNL, "store local child SA SPI for installation", ntohl(spi));
+               this->esp_spi_loc = spi;
+               this->proxy->interface.add_sa(&this->proxy->interface, src, dst, spi,
+                                                                         protocol, reqid, mark, tfc, lifetime,
+                                                                         enc_alg, enc_key, int_alg, int_key, mode,
+                                                                         ipcomp, cpi, encap, esn, inbound, src_ts,
+                                                                         dst_ts);
+               return SUCCESS;
+       }
+       const esa_info_t esa = *(esa_info_t *)(enc_key.ptr);
+       DBG1(DBG_KNL, "adding child SA (isa: %llu, esp_spi_loc: %x, esp_spi_rem:"
+                " %x)", esa.isa_id, ntohl(this->esp_spi_loc), ntohl(spi));
+       if (ike_esa_create_first (1, esa.isa_id, 1, 1, ntohl(this->esp_spi_loc),
+                                                         ntohl(spi)) != TKM_OK)
+       {
+               DBG1(DBG_KNL, "child SA creation failed");
+               return FAILED;
+       }
+       this->esp_spi_loc = 0;
        return this->proxy->interface.add_sa(&this->proxy->interface, src, dst, spi,
                                                                                 protocol, reqid, mark, tfc, lifetime,
-                                                                                enc_alg, enc_key, int_alg, int_key,
+                                                                                enc_alg, esa.enc_key, int_alg, int_key,
                                                                                 mode, ipcomp, cpi, encap, esn, inbound,
                                                                                 src_ts, dst_ts);
 }
@@ -186,6 +214,7 @@ tkm_kernel_ipsec_t *tkm_kernel_ipsec_create()
                                .destroy = _destroy,
                        },
                },
+               .esp_spi_loc = 0,
                .proxy = kernel_netlink_ipsec_create(),
        );
 
index b36353b..a2d40a8 100644 (file)
@@ -20,6 +20,7 @@
 #include <tkm/client.h>
 
 #include "tkm.h"
+#include "tkm_types.h"
 #include "tkm_utils.h"
 #include "tkm_diffie_hellman.h"
 #include "tkm_keymat.h"
@@ -291,8 +292,14 @@ METHOD(tkm_keymat_t, derive_child_keys, bool,
        chunk_t *encr_r, chunk_t *integ_r)
 {
        DBG1(DBG_CHD, "deriving child keys");
-       return this->proxy->derive_child_keys(this->proxy, proposal, dh, nonce_i,
-                       nonce_r, encr_i, integ_i, encr_r, integ_r);
+       *encr_i = chunk_alloc(sizeof(esa_info_t));
+       (*(esa_info_t*)(encr_i->ptr)).isa_id = this->isa_ctx_id;
+       const bool result = this->proxy->derive_child_keys(this->proxy, proposal,
+                                                                                                          dh, nonce_i, nonce_r,
+                                                                                                          &(*(esa_info_t*)(encr_i->ptr)).enc_key,
+                                                                                                          integ_i, encr_r,
+                                                                                                          integ_r);
+       return result;
 }
 
 METHOD(keymat_t, get_aead, aead_t*,
diff --git a/src/charon-tkm/src/tkm/tkm_types.h b/src/charon-tkm/src/tkm/tkm_types.h
new file mode 100644 (file)
index 0000000..8c65348
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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_TYPES_H_
+#define TKM_TYPES_H_
+
+typedef struct esa_info_t esa_info_t;
+
+struct esa_info_t {
+       isa_id_type isa_id;
+       chunk_t enc_key;
+};
+
+#endif /** TKM_TYPES_H_ */