*/
rng_t *rng;
- /**
- * Local CHILD SA SPI.
- */
- uint32_t esp_spi_loc;
-
/**
* CHILD/ESP SA database.
*/
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;
}
},
},
.rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
- .esp_spi_loc = 0,
.sad = tkm_kernel_sad_create(),
);
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;
}
#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_ */