diff options
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_kernel_ipsec.c | 19 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_keymat.c | 38 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_types.h | 47 |
3 files changed, 87 insertions, 17 deletions
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c index c97869d9c..eaec4c263 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c +++ b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c @@ -46,11 +46,6 @@ struct private_tkm_kernel_ipsec_t { rng_t *rng; /** - * Local CHILD SA SPI. - */ - uint32_t esp_spi_loc; - - /** * CHILD/ESP SA database. */ tkm_kernel_sad_t *sad; @@ -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(), ); diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c index 0b9612c85..f9fd57ae0 100644 --- a/src/charon-tkm/src/tkm/tkm_keymat.c +++ b/src/charon-tkm/src/tkm/tkm_keymat.c @@ -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; } diff --git a/src/charon-tkm/src/tkm/tkm_types.h b/src/charon-tkm/src/tkm/tkm_types.h index a33066444..65f45cf68 100644 --- a/src/charon-tkm/src/tkm/tkm_types.h +++ b/src/charon-tkm/src/tkm/tkm_types.h @@ -17,10 +17,57 @@ #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_ */ |