]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kdf: Add plugin that provides a default prf+ implementation
authorTobias Brunner <tobias@strongswan.org>
Fri, 11 Feb 2022 13:49:49 +0000 (14:49 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Apr 2022 16:54:24 +0000 (18:54 +0200)
configure.ac
src/libstrongswan/Android.mk
src/libstrongswan/Makefile.am
src/libstrongswan/plugins/kdf/Makefile.am [new file with mode: 0644]
src/libstrongswan/plugins/kdf/kdf_plugin.c [new file with mode: 0644]
src/libstrongswan/plugins/kdf/kdf_plugin.h [new file with mode: 0644]
src/libstrongswan/plugins/kdf/kdf_prf_plus.c [new file with mode: 0644]
src/libstrongswan/plugins/kdf/kdf_prf_plus.h [new file with mode: 0644]

index 86e50a366059d2178661f05cae1babe5964cb9c2..04a1c5ce32fa6b758241abbc565495d32645c2fa 100644 (file)
@@ -148,6 +148,7 @@ ARG_ENABL_SET([gcrypt],         [enables the libgcrypt plugin.])
 ARG_DISBL_SET([gmp],            [disable GNU MP (libgmp) based crypto implementation plugin.])
 ARG_DISBL_SET([curve25519],     [disable Curve25519 Diffie-Hellman plugin.])
 ARG_DISBL_SET([hmac],           [disable HMAC crypto implementation plugin.])
+ARG_DISBL_SET([kdf],            [disable KDF (prf+) implementation plugin.])
 ARG_ENABL_SET([md4],            [enable MD4 software implementation plugin.])
 ARG_DISBL_SET([md5],            [disable MD5 software implementation plugin.])
 ARG_ENABL_SET([mgf1],           [enable the MGF1 software implementation plugin.])
@@ -1502,6 +1503,7 @@ ADD_PLUGIN([chapoly],              [s charon scripts nm cmd])
 ADD_PLUGIN([xcbc],                 [s charon nm cmd])
 ADD_PLUGIN([cmac],                 [s charon nm cmd])
 ADD_PLUGIN([hmac],                 [s charon pki scripts nm cmd])
+ADD_PLUGIN([kdf],                  [s charon pki scripts nm cmd])
 ADD_PLUGIN([ctr],                  [s charon scripts nm cmd])
 ADD_PLUGIN([ccm],                  [s charon scripts nm cmd])
 ADD_PLUGIN([gcm],                  [s charon scripts nm cmd])
@@ -1656,6 +1658,7 @@ AM_CONDITIONAL(USE_DNSKEY, test x$dnskey = xtrue)
 AM_CONDITIONAL(USE_SSHKEY, test x$sshkey = xtrue)
 AM_CONDITIONAL(USE_PEM, test x$pem = xtrue)
 AM_CONDITIONAL(USE_HMAC, test x$hmac = xtrue)
+AM_CONDITIONAL(USE_KDF, test x$kdf = xtrue)
 AM_CONDITIONAL(USE_CMAC, test x$cmac = xtrue)
 AM_CONDITIONAL(USE_XCBC, test x$xcbc = xtrue)
 AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue)
@@ -1921,6 +1924,7 @@ AC_CONFIG_FILES([
        src/libstrongswan/plugins/random/Makefile
        src/libstrongswan/plugins/nonce/Makefile
        src/libstrongswan/plugins/hmac/Makefile
+       src/libstrongswan/plugins/kdf/Makefile
        src/libstrongswan/plugins/xcbc/Makefile
        src/libstrongswan/plugins/x509/Makefile
        src/libstrongswan/plugins/revocation/Makefile
index fa9f2b2448bc5320b8bcaf074691f16782d8a3bb..515fd8f76b5df7f8a64ba80149d86170eb1da33f 100644 (file)
@@ -92,6 +92,8 @@ endif
 
 LOCAL_SRC_FILES += $(call add_plugin, hmac)
 
+LOCAL_SRC_FILES += $(call add_plugin, kdf)
+
 LOCAL_SRC_FILES += $(call add_plugin, md4)
 
 LOCAL_SRC_FILES += $(call add_plugin, md5)
index 791b2bcff8e9f70009c3ee86408307d90bf4ea44..81e841381f2372d3d690882541c614e99df4b978 100644 (file)
@@ -395,6 +395,13 @@ if MONOLITHIC
 endif
 endif
 
+if USE_KDF
+  SUBDIRS += plugins/kdf
+if MONOLITHIC
+  libstrongswan_la_LIBADD += plugins/kdf/libstrongswan-kdf.la
+endif
+endif
+
 if USE_CMAC
   SUBDIRS += plugins/cmac
 if MONOLITHIC
diff --git a/src/libstrongswan/plugins/kdf/Makefile.am b/src/libstrongswan/plugins/kdf/Makefile.am
new file mode 100644 (file)
index 0000000..2488b57
--- /dev/null
@@ -0,0 +1,17 @@
+AM_CPPFLAGS = \
+       -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+       $(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-kdf.la
+else
+plugin_LTLIBRARIES = libstrongswan-kdf.la
+endif
+
+libstrongswan_kdf_la_SOURCES = \
+       kdf_plugin.h kdf_plugin.c \
+       kdf_prf_plus.h kdf_prf_plus.c
+
+libstrongswan_kdf_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/kdf/kdf_plugin.c b/src/libstrongswan/plugins/kdf/kdf_plugin.c
new file mode 100644 (file)
index 0000000..d9248a7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 Tobias Brunner, codelabs GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "kdf_plugin.h"
+#include "kdf_prf_plus.h"
+
+#include <library.h>
+
+typedef struct private_kdf_plugin_t private_kdf_plugin_t;
+
+/**
+ * Private data
+ */
+struct private_kdf_plugin_t {
+
+       /**
+        * Public interface
+        */
+       kdf_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+       private_kdf_plugin_t *this)
+{
+       return "kdf";
+}
+
+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_PROVIDE(KDF, KDF_PRF_PLUS),
+                               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),
+       };
+       *features = f;
+       return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+       private_kdf_plugin_t *this)
+{
+       free(this);
+}
+
+/*
+ * Described in header
+ */
+plugin_t *kdf_plugin_create()
+{
+       private_kdf_plugin_t *this;
+
+       INIT(this,
+               .public = {
+                       .plugin = {
+                               .get_name = _get_name,
+                               .get_features = _get_features,
+                               .destroy = _destroy,
+                       },
+               },
+       );
+
+       return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/kdf/kdf_plugin.h b/src/libstrongswan/plugins/kdf/kdf_plugin.h
new file mode 100644 (file)
index 0000000..e6f6cd8
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 Tobias Brunner, codelabs GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @defgroup kdf_p kdf
+ * @ingroup plugins
+ *
+ * @defgroup kdf_plugin kdf_plugin
+ * @{ @ingroup kdf_p
+ */
+
+#ifndef KDF_PLUGIN_H_
+#define KDF_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct kdf_plugin_t kdf_plugin_t;
+
+/**
+ * Plugin implementing the key derivation functions (KDF) in software.
+ */
+struct kdf_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+#endif /** KDF_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/kdf/kdf_prf_plus.c b/src/libstrongswan/plugins/kdf/kdf_prf_plus.c
new file mode 100644 (file)
index 0000000..f21dcf2
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 Tobias Brunner, codelabs GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "kdf_prf_plus.h"
+
+#include <crypto/prf_plus.h>
+
+typedef struct private_kdf_t private_kdf_t;
+
+/**
+ * Private data.
+ */
+struct private_kdf_t {
+
+       /**
+        * Public interface.
+        */
+       kdf_t public;
+
+       /**
+        * Underlying PRF.
+        */
+       prf_t *prf;
+
+       /**
+        * Salt value.
+        */
+       chunk_t salt;
+};
+
+METHOD(kdf_t, get_type, key_derivation_function_t,
+       private_kdf_t *this)
+{
+       return KDF_PRF_PLUS;
+}
+
+METHOD(kdf_t, get_bytes, bool,
+       private_kdf_t *this, size_t out_len, uint8_t *buffer)
+{
+       prf_plus_t *prf_plus;
+       bool success;
+
+       prf_plus = prf_plus_create(this->prf, TRUE, this->salt);
+       if (!prf_plus)
+       {
+               return FALSE;
+       }
+       success = prf_plus->get_bytes(prf_plus, out_len, buffer);
+       prf_plus->destroy(prf_plus);
+       return success;
+}
+
+METHOD(kdf_t, allocate_bytes, bool,
+       private_kdf_t *this, size_t out_len, chunk_t *chunk)
+{
+       *chunk = chunk_alloc(out_len);
+
+       if (!get_bytes(this, out_len, chunk->ptr))
+       {
+               chunk_free(chunk);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+METHOD(kdf_t, set_param, bool,
+       private_kdf_t *this, kdf_param_t param, ...)
+{
+       chunk_t chunk;
+       bool success = FALSE;
+
+       switch (param)
+       {
+               case KDF_PARAM_KEY:
+                       VA_ARGS_GET(param, chunk);
+                       success = this->prf->set_key(this->prf, chunk);
+                       break;
+               case KDF_PARAM_SALT:
+                       VA_ARGS_GET(param, chunk);
+                       chunk_clear(&this->salt);
+                       this->salt = chunk_clone(chunk);
+                       success = TRUE;
+                       break;
+       }
+       return success;
+}
+
+METHOD(kdf_t, destroy, void,
+       private_kdf_t *this)
+{
+       this->prf->destroy(this->prf);
+       chunk_clear(&this->salt);
+       free(this);
+}
+
+/*
+ * Described in header
+ */
+kdf_t *kdf_prf_plus_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)
+       {
+               return NULL;
+       }
+
+       VA_ARGS_VGET(args, prf_alg);
+       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);
+               return NULL;
+       }
+
+       INIT(this,
+               .public = {
+                       .get_type = _get_type,
+                       .get_bytes = _get_bytes,
+                       .allocate_bytes = _allocate_bytes,
+                       .set_param = _set_param,
+                       .destroy = _destroy,
+               },
+               .prf = prf,
+       );
+
+       return &this->public;
+}
diff --git a/src/libstrongswan/plugins/kdf/kdf_prf_plus.h b/src/libstrongswan/plugins/kdf/kdf_prf_plus.h
new file mode 100644 (file)
index 0000000..897f1af
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 Tobias Brunner, codelabs GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * Implements prf+ as defined in RFC 7296, section 2.13:
+ *
+ * @verbatim
+     prf+ (K,S) = T1 | T2 | T3 | T4 | ...
+
+     where:
+     T1 = prf (K, S | 0x01)
+     T2 = prf (K, T1 | S | 0x02)
+     T3 = prf (K, T2 | S | 0x03)
+     T4 = prf (K, T3 | S | 0x04)
+     ...
+ * @endverbatim
+ *
+ * @defgroup kdf_prf_plus kdf_prf_plus
+ * @{ @ingroup kdf_p
+ */
+
+#ifndef KDF_PRF_PLUS_H_
+#define KDF_PRF_PLUS_H_
+
+#include <crypto/kdfs/kdf.h>
+
+/**
+ * Create a kdf_t object
+ *
+ * @param algo                 KDF_PRF_PLUS
+ * @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);
+
+#endif /** KDF_PRF_PLUS_H_ @}*/