]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
crypto-factory: Add constructor and methods to create KDFs
authorTobias Brunner <tobias@strongswan.org>
Wed, 9 Feb 2022 15:16:20 +0000 (16:16 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Apr 2022 16:54:24 +0000 (18:54 +0200)
Using some arguments directly in the constructor will allow us to fall
back on other implementations.

src/libstrongswan/crypto/crypto_factory.c
src/libstrongswan/crypto/crypto_factory.h

index 62b9806966fa56b1eb8e0106bc60c025df0fe64f..3fce7b72b77f796dcf2c9648deab5c16dc93d702 100644 (file)
@@ -53,6 +53,7 @@ struct entry_t {
                hasher_constructor_t create_hasher;
                prf_constructor_t create_prf;
                xof_constructor_t create_xof;
+               kdf_constructor_t create_kdf;
                drbg_constructor_t create_drbg;
                rng_constructor_t create_rng;
                nonce_gen_constructor_t create_nonce_gen;
@@ -103,6 +104,11 @@ struct private_crypto_factory_t {
         */
        linked_list_t *xofs;
 
+       /**
+        * registered kdfs, as entry_t
+        */
+       linked_list_t *kdfs;
+
        /**
         * registered drbgs, as entry_t
         */
@@ -348,6 +354,34 @@ METHOD(crypto_factory_t, create_xof, xof_t*,
        return xof;
 }
 
+METHOD(crypto_factory_t, create_kdf, kdf_t*,
+       private_crypto_factory_t *this, key_derivation_function_t algo, ...)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       va_list args;
+       kdf_t *kdf = NULL;
+
+       this->lock->read_lock(this->lock);
+       enumerator = this->kdfs->create_enumerator(this->kdfs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->algo == algo)
+               {
+                       va_start(args, algo);
+                       kdf = entry->create_kdf(algo, args);
+                       va_end(args);
+                       if (kdf)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return kdf;
+}
+
 METHOD(crypto_factory_t, create_drbg, drbg_t*,
        private_crypto_factory_t *this, drbg_type_t type, uint32_t strength,
        rng_t *entropy, chunk_t personalization_str)
@@ -749,6 +783,34 @@ METHOD(crypto_factory_t, remove_xof, void,
        this->lock->unlock(this->lock);
 }
 
+METHOD(crypto_factory_t, add_kdf, bool,
+       private_crypto_factory_t *this, key_derivation_function_t algo,
+       const char *plugin_name, kdf_constructor_t create)
+{
+       add_entry(this, this->kdfs, algo, plugin_name, 0, create);
+       return TRUE;
+}
+
+METHOD(crypto_factory_t, remove_kdf, void,
+       private_crypto_factory_t *this, kdf_constructor_t create)
+{
+       entry_t *entry;
+       enumerator_t *enumerator;
+
+       this->lock->write_lock(this->lock);
+       enumerator = this->kdfs->create_enumerator(this->kdfs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create_kdf == create)
+               {
+                       this->kdfs->remove_at(this->kdfs, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+}
+
 METHOD(crypto_factory_t, add_drbg, bool,
        private_crypto_factory_t *this, drbg_type_t type,
        const char *plugin_name, drbg_constructor_t create)
@@ -1058,6 +1120,30 @@ METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
        return create_enumerator(this, this->xofs, xof_filter);
 }
 
+CALLBACK(kdf_filter, bool,
+       void *n, enumerator_t *orig, va_list args)
+{
+       entry_t *entry;
+       key_derivation_function_t *algo;
+       const char **plugin_name;
+
+       VA_ARGS_VGET(args, algo, plugin_name);
+
+       if (orig->enumerate(orig, &entry))
+       {
+               *algo = entry->algo;
+               *plugin_name = entry->plugin_name;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+METHOD(crypto_factory_t, create_kdf_enumerator, enumerator_t*,
+       private_crypto_factory_t *this)
+{
+       return create_enumerator(this, this->kdfs, kdf_filter);
+}
+
 CALLBACK(drbg_filter, bool,
        void *n, enumerator_t *orig, va_list args)
 {
@@ -1323,6 +1409,7 @@ METHOD(crypto_factory_t, destroy, void,
        this->hashers->destroy(this->hashers);
        this->prfs->destroy(this->prfs);
        this->xofs->destroy(this->xofs);
+       this->kdfs->destroy(this->kdfs);
        this->drbgs->destroy(this->drbgs);
        this->rngs->destroy(this->rngs);
        this->nonce_gens->destroy(this->nonce_gens);
@@ -1347,6 +1434,7 @@ crypto_factory_t *crypto_factory_create()
                        .create_hasher = _create_hasher,
                        .create_prf = _create_prf,
                        .create_xof = _create_xof,
+                       .create_kdf = _create_kdf,
                        .create_drbg = _create_drbg,
                        .create_rng = _create_rng,
                        .create_nonce_gen = _create_nonce_gen,
@@ -1363,6 +1451,8 @@ crypto_factory_t *crypto_factory_create()
                        .remove_prf = _remove_prf,
                        .add_xof = _add_xof,
                        .remove_xof = _remove_xof,
+                       .add_kdf = _add_kdf,
+                       .remove_kdf = _remove_kdf,
                        .add_drbg = _add_drbg,
                        .remove_drbg = _remove_drbg,
                        .add_rng = _add_rng,
@@ -1377,6 +1467,7 @@ crypto_factory_t *crypto_factory_create()
                        .create_hasher_enumerator = _create_hasher_enumerator,
                        .create_prf_enumerator = _create_prf_enumerator,
                        .create_xof_enumerator = _create_xof_enumerator,
+                       .create_kdf_enumerator = _create_kdf_enumerator,
                        .create_drbg_enumerator = _create_drbg_enumerator,
                        .create_dh_enumerator = _create_dh_enumerator,
                        .create_rng_enumerator = _create_rng_enumerator,
@@ -1391,6 +1482,7 @@ crypto_factory_t *crypto_factory_create()
                .hashers = linked_list_create(),
                .prfs = linked_list_create(),
                .xofs = linked_list_create(),
+               .kdfs = linked_list_create(),
                .drbgs = linked_list_create(),
                .rngs = linked_list_create(),
                .nonce_gens = linked_list_create(),
index 3901cce805440ab04fc04e11cda2022025861223..3dd29a2ff8f5d4686be1ca3046a6b36e4687f861 100644 (file)
@@ -33,6 +33,7 @@ typedef struct crypto_factory_t crypto_factory_t;
 #include <crypto/prfs/prf.h>
 #include <crypto/rngs/rng.h>
 #include <crypto/xofs/xof.h>
+#include <crypto/kdfs/kdf.h>
 #include <crypto/drbgs/drbg.h>
 #include <crypto/nonce_gen.h>
 #include <crypto/diffie_hellman.h>
@@ -70,6 +71,14 @@ typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
  */
 typedef xof_t* (*xof_constructor_t)(ext_out_function_t algo);
 
+/**
+ * Constructor function for key derivation functions
+ *
+ * The additional arguments depend on the algorithm, see comments
+ * for key_derivation_function_t.
+ */
+typedef kdf_t* (*kdf_constructor_t)(key_derivation_function_t algo, va_list args);
+
 /**
  * Constructor function for deterministic random bit generators
  */
@@ -154,6 +163,20 @@ struct crypto_factory_t {
         */
        xof_t* (*create_xof)(crypto_factory_t *this, ext_out_function_t algo);
 
+
+       /**
+        * Create a key derivation function instance.
+        *
+        * Additional arguments depend on the KDF, please refer to the comments in
+        * key_derivation_function_t.
+        *
+        * @param algo                  KDF to create
+        * @param ...                   arguments depending on algo
+        * @return                              kdf_t instance, NULL if not supported
+        */
+       kdf_t* (*create_kdf)(crypto_factory_t *this,
+                                                key_derivation_function_t algo, ...);
+
        /**
         * Create a deterministic random bit generator instance.
         *
@@ -305,6 +328,24 @@ struct crypto_factory_t {
         */
        void (*remove_xof)(crypto_factory_t *this, xof_constructor_t create);
 
+       /**
+        * Register a kdf constructor.
+        *
+        * @param algo                  algorithm to constructor
+        * @param plugin_name   plugin that registered this algorithm
+        * @param create                constructor function for that algorithm
+        * @return                              TRUE if registered, FALSE if test vector failed
+        */
+       bool (*add_kdf)(crypto_factory_t *this, key_derivation_function_t algo,
+                                       const char *plugin_name, kdf_constructor_t create);
+
+       /**
+        * Unregister a kdf constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_kdf)(crypto_factory_t *this, kdf_constructor_t create);
+
        /**
         * Register a drbg constructor.
         *
@@ -419,6 +460,13 @@ struct crypto_factory_t {
         */
        enumerator_t* (*create_xof_enumerator)(crypto_factory_t *this);
 
+       /**
+        * Create an enumerator over all registered KDFs.
+        *
+        * @return                              enumerator over key_derivation_function_t, plugin
+        */
+       enumerator_t* (*create_kdf_enumerator)(crypto_factory_t *this);
+
        /**
         * Create an enumerator over all registered DRBGs.
         *