From: Tobias Brunner Date: Mon, 14 Mar 2022 16:16:17 +0000 (+0100) Subject: kdf: Implement wrapper for IKEv2 PRFs X-Git-Tag: 5.9.6rc1~2^2~5 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=0339ce34f6d726debcac9d0e8f615d27407a8fa9;p=thirdparty%2Fstrongswan.git kdf: Implement wrapper for IKEv2 PRFs --- diff --git a/src/libstrongswan/plugins/kdf/Makefile.am b/src/libstrongswan/plugins/kdf/Makefile.am index 2488b57fcd..6b89de6ae9 100644 --- a/src/libstrongswan/plugins/kdf/Makefile.am +++ b/src/libstrongswan/plugins/kdf/Makefile.am @@ -12,6 +12,6 @@ endif libstrongswan_kdf_la_SOURCES = \ kdf_plugin.h kdf_plugin.c \ - kdf_prf_plus.h kdf_prf_plus.c + kdf_kdf.h kdf_kdf.c libstrongswan_kdf_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/kdf/kdf_prf_plus.c b/src/libstrongswan/plugins/kdf/kdf_kdf.c similarity index 74% rename from src/libstrongswan/plugins/kdf/kdf_prf_plus.c rename to src/libstrongswan/plugins/kdf/kdf_kdf.c index 8e3d1ccaa6..f6baf3f7be 100644 --- a/src/libstrongswan/plugins/kdf/kdf_prf_plus.c +++ b/src/libstrongswan/plugins/kdf/kdf_kdf.c @@ -20,7 +20,7 @@ * THE SOFTWARE. */ -#include "kdf_prf_plus.h" +#include "kdf_kdf.h" typedef struct private_kdf_t private_kdf_t; @@ -34,6 +34,11 @@ struct private_kdf_t { */ kdf_t public; + /** + * KDF type. + */ + key_derivation_function_t type; + /** * Underlying PRF. */ @@ -48,16 +53,20 @@ struct private_kdf_t { METHOD(kdf_t, get_type, key_derivation_function_t, private_kdf_t *this) { - return KDF_PRF_PLUS; + return this->type; } METHOD(kdf_t, get_length, size_t, private_kdf_t *this) { - return SIZE_MAX; + if (this->type == KDF_PRF_PLUS) + { + return SIZE_MAX; + } + return this->prf->get_block_size(this->prf); } -METHOD(kdf_t, get_bytes, bool, +METHOD(kdf_t, get_bytes_prf_plus, bool, private_kdf_t *this, size_t out_len, uint8_t *buffer) { chunk_t block, previous = chunk_empty; @@ -93,12 +102,27 @@ METHOD(kdf_t, get_bytes, bool, return success; } +METHOD(kdf_t, get_bytes, bool, + private_kdf_t *this, size_t out_len, uint8_t *buffer) +{ + if (out_len != get_length(this)) + { + return FALSE; + } + return this->prf->get_bytes(this->prf, this->salt, buffer); +} + METHOD(kdf_t, allocate_bytes, bool, private_kdf_t *this, size_t out_len, chunk_t *chunk) { + if (this->type == KDF_PRF) + { + out_len = out_len ?: get_length(this); + } + *chunk = chunk_alloc(out_len); - if (!get_bytes(this, out_len, chunk->ptr)) + if (!this->public.get_bytes(&this->public, out_len, chunk->ptr)) { chunk_free(chunk); return FALSE; @@ -112,6 +136,22 @@ METHOD(kdf_t, set_param, bool, chunk_t chunk; bool success = FALSE; + if (this->type == KDF_PRF) + { /* IKEv2 uses the nonces etc., which we receive as SALT, as PRF key and + * the DH secret as salt */ + switch (param) + { + case KDF_PARAM_KEY: + param = KDF_PARAM_SALT; + break; + case KDF_PARAM_SALT: + param = KDF_PARAM_KEY; + break; + default: + break; + } + } + switch (param) { case KDF_PARAM_KEY: @@ -139,13 +179,13 @@ METHOD(kdf_t, destroy, void, /* * Described in header */ -kdf_t *kdf_prf_plus_create(key_derivation_function_t algo, va_list args) +kdf_t *kdf_kdf_create(key_derivation_function_t algo, va_list args) { private_kdf_t *this; pseudo_random_function_t prf_alg; prf_t *prf; - if (algo != KDF_PRF_PLUS) + if (algo != KDF_PRF && algo != KDF_PRF_PLUS) { return NULL; } @@ -154,8 +194,9 @@ kdf_t *kdf_prf_plus_create(key_derivation_function_t algo, va_list args) prf = lib->crypto->create_prf(lib->crypto, prf_alg); if (!prf) { - DBG1(DBG_LIB, "failed to create %N for prf+", - pseudo_random_function_names, prf_alg); + DBG1(DBG_LIB, "failed to create %N for %N", + pseudo_random_function_names, prf_alg, + key_derivation_function_names, algo); return NULL; } @@ -168,8 +209,13 @@ kdf_t *kdf_prf_plus_create(key_derivation_function_t algo, va_list args) .set_param = _set_param, .destroy = _destroy, }, + .type = algo, .prf = prf, ); + if (algo == KDF_PRF_PLUS) + { + this->public.get_bytes = _get_bytes_prf_plus; + } return &this->public; } diff --git a/src/libstrongswan/plugins/kdf/kdf_prf_plus.h b/src/libstrongswan/plugins/kdf/kdf_kdf.h similarity index 86% rename from src/libstrongswan/plugins/kdf/kdf_prf_plus.h rename to src/libstrongswan/plugins/kdf/kdf_kdf.h index 897f1af601..272b496cba 100644 --- a/src/libstrongswan/plugins/kdf/kdf_prf_plus.h +++ b/src/libstrongswan/plugins/kdf/kdf_kdf.h @@ -21,7 +21,8 @@ */ /** - * Implements prf+ as defined in RFC 7296, section 2.13: + * Implements a KDF wrapper around PRFs, and prf+ as defined in RFC 7296, + * section 2.13: * * @verbatim prf+ (K,S) = T1 | T2 | T3 | T4 | ... @@ -34,12 +35,12 @@ ... * @endverbatim * - * @defgroup kdf_prf_plus kdf_prf_plus + * @defgroup kdf_kdf kdf_kdf * @{ @ingroup kdf_p */ -#ifndef KDF_PRF_PLUS_H_ -#define KDF_PRF_PLUS_H_ +#ifndef KDF_KDF_H_ +#define KDF_KDF_H_ #include @@ -50,6 +51,6 @@ * @param args pseudo_random_function_t of the underlying PRF * @return kdf_t object, NULL if not supported */ -kdf_t *kdf_prf_plus_create(key_derivation_function_t algo, va_list args); +kdf_t *kdf_kdf_create(key_derivation_function_t algo, va_list args); -#endif /** KDF_PRF_PLUS_H_ @}*/ +#endif /** KDF_KDF_H_ @}*/ diff --git a/src/libstrongswan/plugins/kdf/kdf_plugin.c b/src/libstrongswan/plugins/kdf/kdf_plugin.c index d9248a7301..c2f554e3c0 100644 --- a/src/libstrongswan/plugins/kdf/kdf_plugin.c +++ b/src/libstrongswan/plugins/kdf/kdf_plugin.c @@ -21,7 +21,7 @@ */ #include "kdf_plugin.h" -#include "kdf_prf_plus.h" +#include "kdf_kdf.h" #include @@ -48,7 +48,14 @@ METHOD(plugin_t, get_features, int, private_kdf_plugin_t *this, plugin_feature_t *features[]) { static plugin_feature_t f[] = { - PLUGIN_REGISTER(KDF, kdf_prf_plus_create), + PLUGIN_REGISTER(KDF, kdf_kdf_create), + PLUGIN_PROVIDE(KDF, KDF_PRF), + PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA1), + PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_256), + PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_384), + PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_512), + PLUGIN_SDEPEND(PRF, PRF_AES128_XCBC), + PLUGIN_SDEPEND(PRF, PRF_AES128_CMAC), PLUGIN_PROVIDE(KDF, KDF_PRF_PLUS), PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA1), PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_256),