* THE SOFTWARE.
*/
-#include "kdf_prf_plus.h"
+#include "kdf_kdf.h"
typedef struct private_kdf_t private_kdf_t;
*/
kdf_t public;
+ /**
+ * KDF type.
+ */
+ key_derivation_function_t type;
+
/**
* Underlying PRF.
*/
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;
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;
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:
/*
* 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;
}
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;
}
.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;
}
*/
/**
- * 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 | ...
...
* @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>
* @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_ @}*/
*/
#include "kdf_plugin.h"
-#include "kdf_prf_plus.h"
+#include "kdf_kdf.h"
#include <library.h>
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),