From 62d43ea69483a1f89a56186e9e930538db824cd2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 9 Apr 2019 18:29:10 +0200 Subject: [PATCH] ike-sa-manager: Extract IKE SPI labeling feature from charon-tkm Might be useful for users of other daemons too. Note that compared to the previous implementation in charon-tkm, the mask/label are applied in network order. Closes strongswan/strongswan#134. --- conf/options/charon.opt | 7 ++ src/charon-tkm/src/charon-tkm.c | 4 - src/charon-tkm/src/tkm/tkm_spi_generator.c | 98 ---------------------- src/charon-tkm/src/tkm/tkm_spi_generator.h | 36 -------- src/libcharon/sa/ike_sa_manager.c | 30 +++++++ 5 files changed, 37 insertions(+), 138 deletions(-) delete mode 100644 src/charon-tkm/src/tkm/tkm_spi_generator.c delete mode 100644 src/charon-tkm/src/tkm/tkm_spi_generator.h diff --git a/conf/options/charon.opt b/conf/options/charon.opt index 8fb64bc25..21f6e0833 100644 --- a/conf/options/charon.opt +++ b/conf/options/charon.opt @@ -370,6 +370,13 @@ charon.signature_authentication_constraints = yes certificate chain, are also used as constraints against the signature scheme used by peers during IKEv2. +charon.spi_label = 0x0000000000000000 + Value mixed into the local IKE SPIs after applying _spi_mask_. + +charon.spi_mask = 0x0000000000000000 + Mask applied to local IKE SPIs before mixing in _spi_label_ (bits set will + be replaced with _spi_label_). + charon.spi_min = 0xc0000000 The lower limit for SPIs requested from the kernel for IPsec SAs. diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index 181c6fb8a..57d132406 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -43,7 +43,6 @@ #include "tkm_public_key.h" #include "tkm_cred.h" #include "tkm_encoder.h" -#include "tkm_spi_generator.h" /** * TKM bus listener for IKE authorize events. @@ -316,9 +315,6 @@ int main(int argc, char *argv[]) PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256), PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create), PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"), - PLUGIN_CALLBACK(tkm_spi_generator_register, NULL), - PLUGIN_PROVIDE(CUSTOM, "tkm-spi-generator"), - PLUGIN_DEPENDS(CUSTOM, "libcharon-sa-managers"), }; lib->plugins->add_static_features(lib->plugins, "tkm-backend", features, countof(features), TRUE, NULL, NULL); diff --git a/src/charon-tkm/src/tkm/tkm_spi_generator.c b/src/charon-tkm/src/tkm/tkm_spi_generator.c deleted file mode 100644 index ff4d86c2e..000000000 --- a/src/charon-tkm/src/tkm/tkm_spi_generator.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2015 Reto Buerki - * Copyright (C) 2015 Adrian-Ken Rueegsegger - * HSR 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 . - * - * 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. - */ - -#include -#include -#include - -#include "tkm_spi_generator.h" - -/** - * Get SPI callback arguments - */ -typedef struct { - rng_t *rng; - uint64_t spi_mask; - uint64_t spi_label; -} get_spi_args_t; - -static get_spi_args_t *spi_args; - -/** - * Callback called to generate an IKE SPI. - * - * @param this Callback args containing rng_t and spi mask & label - * @return labeled SPI - */ -CALLBACK(tkm_get_spi, uint64_t, - const get_spi_args_t const *this) -{ - uint64_t spi; - - if (!this->rng->get_bytes(this->rng, sizeof(spi), (uint8_t*)&spi)) - { - return 0; - } - - return (spi & ~this->spi_mask) | this->spi_label; -} - -bool tkm_spi_generator_register(plugin_t *plugin, - plugin_feature_t *feature, - bool reg, void *cb_data) -{ - uint64_t spi_mask, spi_label; - char *spi_val; - rng_t *rng; - - if (reg) - { - rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!rng) - { - return FALSE; - } - - spi_val = lib->settings->get_str(lib->settings, "%s.spi_mask", NULL, - lib->ns); - spi_mask = settings_value_as_uint64(spi_val, 0); - - spi_val = lib->settings->get_str(lib->settings, "%s.spi_label", NULL, - lib->ns); - spi_label = settings_value_as_uint64(spi_val, 0); - - INIT(spi_args, - .rng = rng, - .spi_mask = spi_mask, - .spi_label = spi_label, - ); - - charon->ike_sa_manager->set_spi_cb(charon->ike_sa_manager, - tkm_get_spi, spi_args); - DBG1(DBG_IKE, "using SPI label 0x%.16"PRIx64" and mask 0x%.16"PRIx64, - spi_label, spi_mask); - } - else - { - if (spi_args) - { - DESTROY_IF(spi_args->rng); - free(spi_args); - } - } - - return TRUE; -} diff --git a/src/charon-tkm/src/tkm/tkm_spi_generator.h b/src/charon-tkm/src/tkm/tkm_spi_generator.h deleted file mode 100644 index 08eff4aef..000000000 --- a/src/charon-tkm/src/tkm/tkm_spi_generator.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 Reto Buerki - * Copyright (C) 2015 Adrian-Ken Rueegsegger - * HSR 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 . - * - * 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. - */ - -/** - * @defgroup tkm-spi-generator spi generator - * @{ @ingroup tkm - */ - -#ifndef TKM_SPI_GENERATOR_H_ -#define TKM_SPI_GENERATOR_H_ - -#include - -/** - * Register the TKM SPI generator callback. - * - * @return TRUE on success - */ -bool tkm_spi_generator_register(plugin_t *plugin, - plugin_feature_t *feature, - bool reg, void *cb_data); - -#endif /** TKM_SPI_GENERATOR_H_ @}*/ diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 3bac4b109..1de410d6c 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -413,6 +413,16 @@ struct private_ike_sa_manager_t { */ rwlock_t *spi_lock; + /** + * Mask applied to local SPIs before mixing in the label + */ + uint64_t spi_mask; + + /** + * Label applied to local SPIs + */ + uint64_t spi_label; + /** * reuse existing IKE_SAs in checkout_by_config */ @@ -1010,6 +1020,11 @@ static uint64_t get_spi(private_ike_sa_manager_t *this) spi = 0; } this->spi_lock->unlock(this->spi_lock); + + if (spi) + { + spi = (spi & ~this->spi_mask) | this->spi_label; + } return spi; } @@ -2339,6 +2354,7 @@ static u_int get_nearest_powerof2(u_int n) ike_sa_manager_t *ike_sa_manager_create() { private_ike_sa_manager_t *this; + char *spi_val; u_int i; INIT(this, @@ -2372,6 +2388,20 @@ ike_sa_manager_t *ike_sa_manager_create() return NULL; } this->spi_lock = rwlock_create(RWLOCK_TYPE_DEFAULT); + spi_val = lib->settings->get_str(lib->settings, "%s.spi_mask", NULL, + lib->ns); + this->spi_mask = settings_value_as_uint64(spi_val, 0); + spi_val = lib->settings->get_str(lib->settings, "%s.spi_label", NULL, + lib->ns); + this->spi_label = settings_value_as_uint64(spi_val, 0); + if (this->spi_mask || this->spi_label) + { + DBG1(DBG_IKE, "using SPI label 0x%.16"PRIx64" and mask 0x%.16"PRIx64, + this->spi_label, this->spi_mask); + /* the allocated SPI is assumed to be in network order */ + this->spi_mask = htobe64(this->spi_mask); + this->spi_label = htobe64(this->spi_label); + } this->ikesa_limit = lib->settings->get_int(lib->settings, "%s.ikesa_limit", 0, lib->ns);