kdf: Implement wrapper for IKEv2 PRFs
This commit is contained in:
@@ -12,6 +12,6 @@ endif
|
|||||||
|
|
||||||
libstrongswan_kdf_la_SOURCES = \
|
libstrongswan_kdf_la_SOURCES = \
|
||||||
kdf_plugin.h kdf_plugin.c \
|
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
|
libstrongswan_kdf_la_LDFLAGS = -module -avoid-version
|
||||||
|
|||||||
+55
-9
@@ -20,7 +20,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kdf_prf_plus.h"
|
#include "kdf_kdf.h"
|
||||||
|
|
||||||
typedef struct private_kdf_t private_kdf_t;
|
typedef struct private_kdf_t private_kdf_t;
|
||||||
|
|
||||||
@@ -34,6 +34,11 @@ struct private_kdf_t {
|
|||||||
*/
|
*/
|
||||||
kdf_t public;
|
kdf_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KDF type.
|
||||||
|
*/
|
||||||
|
key_derivation_function_t type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Underlying PRF.
|
* Underlying PRF.
|
||||||
*/
|
*/
|
||||||
@@ -48,16 +53,20 @@ struct private_kdf_t {
|
|||||||
METHOD(kdf_t, get_type, key_derivation_function_t,
|
METHOD(kdf_t, get_type, key_derivation_function_t,
|
||||||
private_kdf_t *this)
|
private_kdf_t *this)
|
||||||
{
|
{
|
||||||
return KDF_PRF_PLUS;
|
return this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kdf_t, get_length, size_t,
|
METHOD(kdf_t, get_length, size_t,
|
||||||
private_kdf_t *this)
|
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)
|
private_kdf_t *this, size_t out_len, uint8_t *buffer)
|
||||||
{
|
{
|
||||||
chunk_t block, previous = chunk_empty;
|
chunk_t block, previous = chunk_empty;
|
||||||
@@ -93,12 +102,27 @@ METHOD(kdf_t, get_bytes, bool,
|
|||||||
return success;
|
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,
|
METHOD(kdf_t, allocate_bytes, bool,
|
||||||
private_kdf_t *this, size_t out_len, chunk_t *chunk)
|
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);
|
*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);
|
chunk_free(chunk);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -112,6 +136,22 @@ METHOD(kdf_t, set_param, bool,
|
|||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
bool success = FALSE;
|
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)
|
switch (param)
|
||||||
{
|
{
|
||||||
case KDF_PARAM_KEY:
|
case KDF_PARAM_KEY:
|
||||||
@@ -139,13 +179,13 @@ METHOD(kdf_t, destroy, void,
|
|||||||
/*
|
/*
|
||||||
* Described in header
|
* 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;
|
private_kdf_t *this;
|
||||||
pseudo_random_function_t prf_alg;
|
pseudo_random_function_t prf_alg;
|
||||||
prf_t *prf;
|
prf_t *prf;
|
||||||
|
|
||||||
if (algo != KDF_PRF_PLUS)
|
if (algo != KDF_PRF && algo != KDF_PRF_PLUS)
|
||||||
{
|
{
|
||||||
return NULL;
|
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);
|
prf = lib->crypto->create_prf(lib->crypto, prf_alg);
|
||||||
if (!prf)
|
if (!prf)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "failed to create %N for prf+",
|
DBG1(DBG_LIB, "failed to create %N for %N",
|
||||||
pseudo_random_function_names, prf_alg);
|
pseudo_random_function_names, prf_alg,
|
||||||
|
key_derivation_function_names, algo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,8 +209,13 @@ kdf_t *kdf_prf_plus_create(key_derivation_function_t algo, va_list args)
|
|||||||
.set_param = _set_param,
|
.set_param = _set_param,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
|
.type = algo,
|
||||||
.prf = prf,
|
.prf = prf,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (algo == KDF_PRF_PLUS)
|
||||||
|
{
|
||||||
|
this->public.get_bytes = _get_bytes_prf_plus;
|
||||||
|
}
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
+7
-6
@@ -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
|
* @verbatim
|
||||||
prf+ (K,S) = T1 | T2 | T3 | T4 | ...
|
prf+ (K,S) = T1 | T2 | T3 | T4 | ...
|
||||||
@@ -34,12 +35,12 @@
|
|||||||
...
|
...
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*
|
*
|
||||||
* @defgroup kdf_prf_plus kdf_prf_plus
|
* @defgroup kdf_kdf kdf_kdf
|
||||||
* @{ @ingroup kdf_p
|
* @{ @ingroup kdf_p
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef KDF_PRF_PLUS_H_
|
#ifndef KDF_KDF_H_
|
||||||
#define KDF_PRF_PLUS_H_
|
#define KDF_KDF_H_
|
||||||
|
|
||||||
#include <crypto/kdfs/kdf.h>
|
#include <crypto/kdfs/kdf.h>
|
||||||
|
|
||||||
@@ -50,6 +51,6 @@
|
|||||||
* @param args pseudo_random_function_t of the underlying PRF
|
* @param args pseudo_random_function_t of the underlying PRF
|
||||||
* @return kdf_t object, NULL if not supported
|
* @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_ @}*/
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "kdf_plugin.h"
|
#include "kdf_plugin.h"
|
||||||
#include "kdf_prf_plus.h"
|
#include "kdf_kdf.h"
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
|
||||||
@@ -48,7 +48,14 @@ METHOD(plugin_t, get_features, int,
|
|||||||
private_kdf_plugin_t *this, plugin_feature_t *features[])
|
private_kdf_plugin_t *this, plugin_feature_t *features[])
|
||||||
{
|
{
|
||||||
static plugin_feature_t f[] = {
|
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_PROVIDE(KDF, KDF_PRF_PLUS),
|
||||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA1),
|
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA1),
|
||||||
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_256),
|
PLUGIN_SDEPEND(PRF, PRF_HMAC_SHA2_256),
|
||||||
|
|||||||
Reference in New Issue
Block a user