Add nonce generator interface
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>
Wed, 2 May 2012 15:49:26 +0000 (17:49 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 18 May 2012 06:15:40 +0000 (08:15 +0200)
Nonce generators (nonce_gen_t) can be used to get or allocate nonces.

Users can request nonce generators from the crypto factory while nonce
plugins register/remove themselves to/from the crypto factory.

src/libstrongswan/Makefile.am
src/libstrongswan/crypto/crypto_factory.c
src/libstrongswan/crypto/crypto_factory.h
src/libstrongswan/crypto/nonce_gen.h [new file with mode: 0644]
src/libstrongswan/plugins/plugin_feature.c
src/libstrongswan/plugins/plugin_feature.h

index 8f3b092..f706575 100644 (file)
@@ -17,6 +17,7 @@ crypto/pkcs9.c crypto/pkcs9.h \
 crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords.h \
 crypto/prfs/prf.c crypto/prfs/prf.h \
 crypto/rngs/rng.c crypto/rngs/rng.h \
+crypto/nonce_gen.h \
 crypto/prf_plus.h crypto/prf_plus.c \
 crypto/signers/signer.c crypto/signers/signer.h \
 crypto/crypto_factory.c crypto/crypto_factory.h \
index 2d13896..a734171 100644 (file)
@@ -50,6 +50,7 @@ struct entry_t {
                hasher_constructor_t create_hasher;
                prf_constructor_t create_prf;
                rng_constructor_t create_rng;
+               nonce_gen_constructor_t create_nonce_gen;
                dh_constructor_t create_dh;
                void *create;
        };
@@ -98,6 +99,11 @@ struct private_crypto_factory_t {
        linked_list_t *rngs;
 
        /**
+        * registered nonce generators, as entry_t
+        */
+       linked_list_t *nonce_gens;
+
+       /**
         * registered diffie hellman, as entry_t
         */
        linked_list_t *dhs;
@@ -329,6 +335,25 @@ METHOD(crypto_factory_t, create_rng, rng_t*,
        return NULL;
 }
 
+METHOD(crypto_factory_t, create_nonce_gen, nonce_gen_t*,
+       private_crypto_factory_t *this)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       nonce_gen_t *nonce_gen = NULL;
+
+       this->lock->read_lock(this->lock);
+       enumerator = this->nonce_gens->create_enumerator(this->nonce_gens);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               nonce_gen = entry->create_nonce_gen();
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+
+       return nonce_gen;
+}
+
 METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
        private_crypto_factory_t *this, diffie_hellman_group_t group, ...)
 {
@@ -618,6 +643,33 @@ METHOD(crypto_factory_t, remove_rng, void,
        this->lock->unlock(this->lock);
 }
 
+METHOD(crypto_factory_t, add_nonce_gen, void,
+       private_crypto_factory_t *this, const char *plugin_name,
+       nonce_gen_constructor_t create)
+{
+       add_entry(this, this->nonce_gens, 0, plugin_name, 0, create);
+}
+
+METHOD(crypto_factory_t, remove_nonce_gen, void,
+       private_crypto_factory_t *this, nonce_gen_constructor_t create)
+{
+       entry_t *entry;
+       enumerator_t *enumerator;
+
+       this->lock->write_lock(this->lock);
+       enumerator = this->nonce_gens->create_enumerator(this->rngs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create_nonce_gen == create)
+               {
+                       this->nonce_gens->remove_at(this->nonce_gens, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+}
+
 METHOD(crypto_factory_t, add_dh, void,
        private_crypto_factory_t *this, diffie_hellman_group_t group,
         const char *plugin_name, dh_constructor_t create)
@@ -820,6 +872,7 @@ METHOD(crypto_factory_t, destroy, void,
        this->hashers->destroy(this->hashers);
        this->prfs->destroy(this->prfs);
        this->rngs->destroy(this->rngs);
+       this->nonce_gens->destroy(this->nonce_gens);
        this->dhs->destroy(this->dhs);
        this->tester->destroy(this->tester);
        this->lock->destroy(this->lock);
@@ -841,6 +894,7 @@ crypto_factory_t *crypto_factory_create()
                        .create_hasher = _create_hasher,
                        .create_prf = _create_prf,
                        .create_rng = _create_rng,
+                       .create_nonce_gen = _create_nonce_gen,
                        .create_dh = _create_dh,
                        .add_crypter = _add_crypter,
                        .remove_crypter = _remove_crypter,
@@ -854,6 +908,8 @@ crypto_factory_t *crypto_factory_create()
                        .remove_prf = _remove_prf,
                        .add_rng = _add_rng,
                        .remove_rng = _remove_rng,
+                       .add_nonce_gen = _add_nonce_gen,
+                       .remove_nonce_gen = _remove_nonce_gen,
                        .add_dh = _add_dh,
                        .remove_dh = _remove_dh,
                        .create_crypter_enumerator = _create_crypter_enumerator,
@@ -872,6 +928,7 @@ crypto_factory_t *crypto_factory_create()
                .hashers = linked_list_create(),
                .prfs = linked_list_create(),
                .rngs = linked_list_create(),
+               .nonce_gens = linked_list_create(),
                .dhs = linked_list_create(),
                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                .tester = crypto_tester_create(),
index 8e5db63..c944348 100644 (file)
@@ -30,6 +30,7 @@ typedef struct crypto_factory_t crypto_factory_t;
 #include <crypto/hashers/hasher.h>
 #include <crypto/prfs/prf.h>
 #include <crypto/rngs/rng.h>
+#include <crypto/nonce_gen.h>
 #include <crypto/diffie_hellman.h>
 #include <crypto/transform.h>
 
@@ -66,6 +67,11 @@ typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
 typedef rng_t* (*rng_constructor_t)(rng_quality_t quality);
 
 /**
+ * Constructor function for nonce generators
+ */
+typedef nonce_gen_t* (*nonce_gen_constructor_t)();
+
+/**
  * Constructor function for diffie hellman
  *
  * The DH constructor accepts additional arguments for:
@@ -132,6 +138,13 @@ struct crypto_factory_t {
        rng_t* (*create_rng)(crypto_factory_t *this, rng_quality_t quality);
 
        /**
+        * Create a nonce generator instance.
+        *
+        * @return                              nonce_gen_t instance, NULL if not supported
+        */
+       nonce_gen_t* (*create_nonce_gen)(crypto_factory_t *this);
+
+       /**
         * Create a diffie hellman instance.
         *
         * Additional arguments are passed to the DH constructor.
@@ -253,6 +266,23 @@ struct crypto_factory_t {
        void (*remove_rng)(crypto_factory_t *this, rng_constructor_t create);
 
        /**
+        * Register a nonce generator.
+        *
+        * @param plugin_name   plugin that registered this algorithm
+        * @param create                constructor function for that nonce generator
+        */
+       void (*add_nonce_gen)(crypto_factory_t *this, const char *plugin_name,
+                                                 nonce_gen_constructor_t create);
+
+       /**
+        * Unregister a nonce generator.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_nonce_gen)(crypto_factory_t *this,
+                                                        nonce_gen_constructor_t create);
+
+       /**
         * Register a diffie hellman constructor.
         *
         * @param group                 dh group to constructor
diff --git a/src/libstrongswan/crypto/nonce_gen.h b/src/libstrongswan/crypto/nonce_gen.h
new file mode 100644 (file)
index 0000000..889d04a
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Adrian-Ken Rueegsegger
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup nonce_gen nonce_gen
+ * @{ @ingroup crypto
+ */
+
+#ifndef NONCE_GEN_H_
+#define NONCE_GEN_H_
+
+typedef struct nonce_gen_t nonce_gen_t;
+
+#include <library.h>
+
+/**
+ * Generic interface for nonce generators.
+ */
+struct nonce_gen_t {
+
+       /**
+        * Generates a nonce and writes it into the buffer.
+        *
+        * @param size          size of nonce in bytes
+        * @param buffer        pointer where the generated nonce will be written
+        */
+       void (*get_nonce) (nonce_gen_t *this, size_t size, u_int8_t *buffer);
+
+       /**
+        * Generates a nonce and allocates space for it.
+        *
+        * @param size          size of nonce in bytes
+        * @param chunk         chunk which will hold the generated nonce
+        */
+       void (*allocate_nonce) (nonce_gen_t *this, size_t size, chunk_t *chunk);
+
+       /**
+        * Destroys a nonce generator object.
+        */
+       void (*destroy) (nonce_gen_t *this);
+};
+
+#endif /** NONCE_GEN_H_ @}*/
index 3305288..7239e51 100644 (file)
@@ -29,6 +29,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
        "PRF",
        "DH",
        "RNG",
+       "NONCE_GEN",
        "PRIVKEY",
        "PRIVKEY_GEN",
        "PRIVKEY_SIGN",
@@ -74,6 +75,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
                                return a->arg.dh_group == b->arg.dh_group;
                        case FEATURE_RNG:
                                return a->arg.rng_quality <= b->arg.rng_quality;
+                       case FEATURE_NONCE_GEN:
+                               return TRUE;
                        case FEATURE_PRIVKEY:
                        case FEATURE_PRIVKEY_GEN:
                        case FEATURE_PUBKEY:
@@ -172,6 +175,12 @@ char* plugin_feature_get_string(plugin_feature_t *feature)
                                return str;
                        }
                        break;
+               case FEATURE_NONCE_GEN:
+                       if (asprintf(&str, "%N", plugin_feature_names, feature->type) > 0)
+                       {
+                               return str;
+                       }
+                       break;
                case FEATURE_PRIVKEY:
                case FEATURE_PRIVKEY_GEN:
                case FEATURE_PUBKEY:
@@ -301,6 +310,10 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
                        lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
                                                                name, reg->arg.reg.f);
                        break;
+               case FEATURE_NONCE_GEN:
+                       lib->crypto->add_nonce_gen(lib->crypto,
+                                                               name, reg->arg.reg.f);
+                       break;
                case FEATURE_PRIVKEY:
                case FEATURE_PRIVKEY_GEN:
                        lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
@@ -372,6 +385,9 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
                case FEATURE_RNG:
                        lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
                        break;
+               case FEATURE_NONCE_GEN:
+                       lib->crypto->remove_nonce_gen(lib->crypto, reg->arg.reg.f);
+                       break;
                case FEATURE_PRIVKEY:
                case FEATURE_PRIVKEY_GEN:
                        lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
index 344d194..25a58a4 100644 (file)
@@ -107,6 +107,8 @@ struct plugin_feature_t {
                FEATURE_DH,
                /** rng_t */
                FEATURE_RNG,
+               /** nonce_gen_t */
+               FEATURE_NONCE_GEN,
                /** generic private key support */
                FEATURE_PRIVKEY,
                /** generating new private keys */
@@ -258,6 +260,7 @@ struct plugin_feature_t {
 #define _PLUGIN_FEATURE_PRF(kind, alg)                                         __PLUGIN_FEATURE(kind, PRF, .prf = alg)
 #define _PLUGIN_FEATURE_DH(kind, group)                                                __PLUGIN_FEATURE(kind, DH, .dh_group = group)
 #define _PLUGIN_FEATURE_RNG(kind, quality)                                     __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality)
+#define _PLUGIN_FEATURE_NONCE_GEN(kind, ...)                           __PLUGIN_FEATURE(kind, NONCE_GEN, .custom = NULL)
 #define _PLUGIN_FEATURE_PRIVKEY(kind, type)                                    __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type)
 #define _PLUGIN_FEATURE_PRIVKEY_GEN(kind, type)                                __PLUGIN_FEATURE(kind, PRIVKEY_GEN, .privkey_gen = type)
 #define _PLUGIN_FEATURE_PRIVKEY_SIGN(kind, scheme)                     __PLUGIN_FEATURE(kind, PRIVKEY_SIGN, .privkey_sign = scheme)
@@ -284,6 +287,7 @@ struct plugin_feature_t {
 #define _PLUGIN_FEATURE_REGISTER_PRF(type, f)                          __PLUGIN_FEATURE_REGISTER(type, f)
 #define _PLUGIN_FEATURE_REGISTER_DH(type, f)                           __PLUGIN_FEATURE_REGISTER(type, f)
 #define _PLUGIN_FEATURE_REGISTER_RNG(type, f)                          __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_NONCE_GEN(type, f)                    __PLUGIN_FEATURE_REGISTER(type, f)
 #define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final)       __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
 #define _PLUGIN_FEATURE_REGISTER_PRIVKEY_GEN(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
 #define _PLUGIN_FEATURE_REGISTER_PUBKEY(type, f, final)                __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)