]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Extend esa_info_t struct
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>
Fri, 14 Sep 2012 15:29:21 +0000 (17:29 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:48 +0000 (15:23 +0100)
Add additional fields to the esa_info_t struct so the necessary data can
be passed from the keymat to the kernel ipsec interface, where ESA
creation and key generation using the TKM takes place.

The information is used during the inbound add_sa call to create an ESP
SA. This makes the hack of storing the local SPI in a kernel interface
variable between subsequent add_sa calls unnecessary.

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

index c97869d9ceeda31edc97f6bc8f431c84d9508d00..eaec4c263fea8e6095f4440c6ed52825d28a7142 100644 (file)
@@ -45,11 +45,6 @@ struct private_tkm_kernel_ipsec_t {
         */
        rng_t *rng;
 
-       /**
-        * Local CHILD SA SPI.
-        */
-       uint32_t esp_spi_loc;
-
        /**
         * CHILD/ESP SA database.
         */
@@ -82,31 +77,28 @@ 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)
 {
-       if (inbound && this->esp_spi_loc == 0)
+       if (!inbound)
        {
-               DBG1(DBG_KNL, "store local child SA SPI for installation", ntohl(spi));
-               this->esp_spi_loc = spi;
                return SUCCESS;
        }
        const esa_info_t esa = *(esa_info_t *)(enc_key.ptr);
        const esa_id_type esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA);
-       DBG1(DBG_KNL, "adding child SA (esa: %llu, isa: %llu, esp_spi_loc: %x, esp_spi_rem:"
-                " %x)", esa_id, esa.isa_id, ntohl(this->esp_spi_loc), ntohl(spi));
+       DBG1(DBG_KNL, "adding child SA (esa: %llu, isa: %llu, esp_spi_loc: %x, "
+                "esp_spi_rem: %x)", esa_id, esa.isa_id, ntohl(spi), ntohl(esa.spi_r));
        if (!this->sad->insert(this->sad, esa_id, src, dst, spi, protocol))
        {
                DBG1(DBG_KNL, "unable to add entry (%llu) to SAD", esa_id);
                tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id);
                return FAILED;
        }
-       if (ike_esa_create_first(esa_id, esa.isa_id, 1, 1, ntohl(this->esp_spi_loc),
-                                                        ntohl(spi)) != TKM_OK)
+       if (ike_esa_create_first(esa_id, esa.isa_id, 1, 1, ntohl(spi),
+                                                        ntohl(esa.spi_r)) != TKM_OK)
        {
                DBG1(DBG_KNL, "child SA (%llu) creation failed", esa_id);
                this->sad->remove(this->sad, esa_id);
                tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id);
                return FAILED;
        }
-       this->esp_spi_loc = 0;
        return SUCCESS;
 }
 
@@ -275,7 +267,6 @@ tkm_kernel_ipsec_t *tkm_kernel_ipsec_create()
                        },
                },
                .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
-               .esp_spi_loc = 0,
                .sad = tkm_kernel_sad_create(),
        );
 
index 0b9612c85995a13fc4ea0308cf42b999b494f985..f9fd57ae03598c495b0a8a86b7ebfc9810c501c9 100644 (file)
@@ -280,9 +280,41 @@ METHOD(tkm_keymat_t, derive_child_keys, bool,
        chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i,
        chunk_t *encr_r, chunk_t *integ_r)
 {
-       DBG1(DBG_CHD, "deriving child keys");
-       *encr_i = chunk_alloc(sizeof(esa_info_t));
-       (*(esa_info_t*)(encr_i->ptr)).isa_id = this->isa_ctx_id;
+       esa_info_t *esa_info_i, *esa_info_r;
+
+       dh_id_type dh_id = 0;
+       if (dh)
+       {
+               dh_id = ((tkm_diffie_hellman_t *)dh)->get_id((tkm_diffie_hellman_t *)dh);
+       }
+
+       INIT(esa_info_i,
+                .isa_id = this->isa_ctx_id,
+                .spi_r = proposal->get_spi(proposal),
+                .nonce_i = chunk_clone(nonce_i),
+                .nonce_r = chunk_clone(nonce_r),
+                .is_encr_r = FALSE,
+                .dh_id = dh_id,
+       );
+
+       INIT(esa_info_r,
+                .isa_id = this->isa_ctx_id,
+                .spi_r = proposal->get_spi(proposal),
+                .nonce_i = chunk_clone(nonce_i),
+                .nonce_r = chunk_clone(nonce_r),
+                .is_encr_r = TRUE,
+                .dh_id = dh_id,
+       );
+
+       DBG1(DBG_CHD, "passing on esa info (isa: %llu, spi_r: %x, dh_id: %llu)",
+                esa_info_i->isa_id, ntohl(esa_info_i->spi_r), esa_info_i->dh_id);
+
+       /* store ESA info in encr_i/r, which is passed to add_sa */
+       *encr_i = chunk_create((u_char *)esa_info_i, sizeof(esa_info_t));
+       *encr_r = chunk_create((u_char *)esa_info_r, sizeof(esa_info_t));
+       *integ_i = chunk_empty;
+       *integ_r = chunk_empty;
+
        return TRUE;
 }
 
index a33066444f43e17a77b04b29d3a247d221305087..65f45cf68e7b487abf91d3000cd7579d944be30b 100644 (file)
 #ifndef TKM_TYPES_H_
 #define TKM_TYPES_H_
 
+#include <tkm/types.h>
+#include <utils/chunk.h>
+
 typedef struct esa_info_t esa_info_t;
 
+/**
+ * ESP SA info data structure.
+ *
+ * This type is used to transfer ESA information from the keymat
+ * derive_child_keys to the kernel IPsec interface add_sa operation. This is
+ * necessary because the CHILD SA key derivation and installation is handled
+ * by a single exchange with the TKM (esa_create*) in add_sa.
+ * For this purpose the out parameters encr_i and encr_r of the
+ * derive_child_keys function are (ab)used and the data is stored in these
+ * data chunks. This is possible since the child SA keys are treated as opaque
+ * values and handed to the add_sa procedure of the kernel interface as-is
+ * without any processing.
+ */
 struct esa_info_t {
+
+       /**
+        * ISA context id.
+        */
        isa_id_type isa_id;
+
+       /**
+        * Responder SPI of child SA.
+        */
+       esp_spi_type spi_r;
+
+       /**
+        * Initiator nonce.
+        */
+       chunk_t nonce_i;
+
+       /**
+        * Responder nonce.
+        */
+       chunk_t nonce_r;
+
+       /**
+        * Flag specifying if this esa info struct is contained in encr_r.
+        * It is set to TRUE for encr_r and FALSE for encr_i.
+        */
+       bool is_encr_r;
+
+       /**
+        * Diffie-Hellman context id.
+        */
+       dh_id_type dh_id;
+
 };
 
 #endif /** TKM_TYPES_H_ */