]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kdf: Implement wrapper for IKEv2 PRFs
authorTobias Brunner <tobias@strongswan.org>
Mon, 14 Mar 2022 16:16:17 +0000 (17:16 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Apr 2022 17:02:56 +0000 (19:02 +0200)
src/libstrongswan/plugins/kdf/Makefile.am
src/libstrongswan/plugins/kdf/kdf_kdf.c [moved from src/libstrongswan/plugins/kdf/kdf_prf_plus.c with 74% similarity]
src/libstrongswan/plugins/kdf/kdf_kdf.h [moved from src/libstrongswan/plugins/kdf/kdf_prf_plus.h with 86% similarity]
src/libstrongswan/plugins/kdf/kdf_plugin.c

index 2488b57fcdd707ebf3fcdd27d24ca5096b8086b8..6b89de6ae9e5bcb70606ee6f587757636346e5d1 100644 (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
similarity index 74%
rename from src/libstrongswan/plugins/kdf/kdf_prf_plus.c
rename to src/libstrongswan/plugins/kdf/kdf_kdf.c
index 8e3d1ccaa61857a9494878166247b45ac4b2b233..f6baf3f7be53610977696978f4d814e7f8e8299f 100644 (file)
@@ -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;
 }
similarity index 86%
rename from src/libstrongswan/plugins/kdf/kdf_prf_plus.h
rename to src/libstrongswan/plugins/kdf/kdf_kdf.h
index 897f1af6014ceb9897859f20e50254deec83bc45..272b496cba1e0e9e29618fbef0ed5a4a210e27c1 100644 (file)
@@ -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 | ...
      ...
  * @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_ @}*/
index d9248a73010ea65bf70883abc3a11b48aa979e77..c2f554e3c06c04a3d0a91cfb873437f80cfa740b 100644 (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),