kdf: Implement wrapper for IKEv2 PRFs

This commit is contained in:
Tobias Brunner
2022-04-14 19:02:56 +02:00
parent ad0e94b6ed
commit 0339ce34f6
4 changed files with 72 additions and 18 deletions
+1 -1
View File
@@ -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
@@ -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;
}
@@ -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 <crypto/kdfs/kdf.h>
@@ -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_ @}*/
+9 -2
View File
@@ -21,7 +21,7 @@
*/
#include "kdf_plugin.h"
#include "kdf_prf_plus.h"
#include "kdf_kdf.h"
#include <library.h>
@@ -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),