xof: Defined Extended Output Functions
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 28 Jul 2016 12:42:42 +0000 (14:42 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 29 Jul 2016 10:36:14 +0000 (12:36 +0200)
14 files changed:
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/vici/vici_query.c
src/libstrongswan/Makefile.am
src/libstrongswan/crypto/crypto_factory.c
src/libstrongswan/crypto/crypto_factory.h
src/libstrongswan/crypto/crypto_tester.c
src/libstrongswan/crypto/crypto_tester.h
src/libstrongswan/crypto/transform.c
src/libstrongswan/crypto/transform.h
src/libstrongswan/crypto/xofs/xof.c [new file with mode: 0644]
src/libstrongswan/crypto/xofs/xof.h [new file with mode: 0644]
src/libstrongswan/plugins/plugin_feature.c
src/libstrongswan/plugins/plugin_feature.h
src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c

index 6c5703a..cec2657 100644 (file)
@@ -844,6 +844,7 @@ static void list_algs(FILE *out)
        integrity_algorithm_t integrity;
        hash_algorithm_t hash;
        pseudo_random_function_t prf;
+       ext_out_function_t xof;
        diffie_hellman_group_t group;
        rng_quality_t quality;
        const char *plugin_name;
@@ -891,6 +892,14 @@ static void list_algs(FILE *out)
                print_alg(out, &len, pseudo_random_function_names, prf, plugin_name);
        }
        enumerator->destroy(enumerator);
+       fprintf(out, "\n  xof:       ");
+       len = 13;
+       enumerator = lib->crypto->create_xof_enumerator(lib->crypto);
+       while (enumerator->enumerate(enumerator, &xof, &plugin_name))
+       {
+               print_alg(out, &len, ext_out_function_names, xof, plugin_name);
+       }
+       enumerator->destroy(enumerator);
        fprintf(out, "\n  dh-group:  ");
        len = 13;
        enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
index 04cea00..828b619 100644 (file)
@@ -1072,6 +1072,7 @@ CALLBACK(get_algorithms, vici_message_t*,
        integrity_algorithm_t integrity;
        hash_algorithm_t hash;
        pseudo_random_function_t prf;
+       ext_out_function_t xof;
        diffie_hellman_group_t group;
        rng_quality_t quality;
        const char *plugin_name;
@@ -1123,6 +1124,15 @@ CALLBACK(get_algorithms, vici_message_t*,
        enumerator->destroy(enumerator);
        b->end_section(b);
 
+       b->begin_section(b, "xof");
+       enumerator = lib->crypto->create_xof_enumerator(lib->crypto);
+       while (enumerator->enumerate(enumerator, &xof, &plugin_name))
+       {
+               add_algorithm(b, ext_out_function_names, xof, plugin_name);
+       }
+       enumerator->destroy(enumerator);
+       b->end_section(b);
+
        b->begin_section(b, "dh");
        enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
        while (enumerator->enumerate(enumerator, &group, &plugin_name))
index 9be93f1..965bf7a 100644 (file)
@@ -15,6 +15,7 @@ crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
 crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
 crypto/iv/iv_gen_null.c \
 crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \
+crypto/xofs/xof.h crypto/xofs/xof.c \
 credentials/credential_factory.c credentials/builder.c \
 credentials/cred_encoding.c credentials/keys/private_key.c \
 credentials/keys/public_key.c credentials/keys/shared_key.c \
index 35dcf25..bab59a0 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Copyright (C) 2013-2014 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR 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
@@ -51,6 +52,7 @@ struct entry_t {
                signer_constructor_t create_signer;
                hasher_constructor_t create_hasher;
                prf_constructor_t create_prf;
+               xof_constructor_t create_xof;
                rng_constructor_t create_rng;
                nonce_gen_constructor_t create_nonce_gen;
                dh_constructor_t create_dh;
@@ -96,6 +98,11 @@ struct private_crypto_factory_t {
        linked_list_t *prfs;
 
        /**
+        * registered xofs, as entry_t
+        */
+       linked_list_t *xofs;
+
+       /**
         * registered rngs, as entry_t
         */
        linked_list_t *rngs;
@@ -303,6 +310,38 @@ METHOD(crypto_factory_t, create_prf, prf_t*,
        return prf;
 }
 
+METHOD(crypto_factory_t, create_xof, xof_t*,
+       private_crypto_factory_t *this, ext_out_function_t algo)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       xof_t *xof = NULL;
+
+       this->lock->read_lock(this->lock);
+       enumerator = this->xofs->create_enumerator(this->xofs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->algo == algo)
+               {
+                       if (this->test_on_create &&
+                               !this->tester->test_xof(this->tester, algo,
+                                                                               entry->create_xof, NULL,
+                                                                               default_plugin_name))
+                       {
+                               continue;
+                       }
+                       xof = entry->create_xof(algo);
+                       if (xof)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return xof;
+}
+
 METHOD(crypto_factory_t, create_rng, rng_t*,
        private_crypto_factory_t *this, rng_quality_t quality)
 {
@@ -633,6 +672,43 @@ METHOD(crypto_factory_t, remove_prf, void,
        this->lock->unlock(this->lock);
 }
 
+METHOD(crypto_factory_t, add_xof, bool,
+       private_crypto_factory_t *this, ext_out_function_t algo,
+       const char *plugin_name, xof_constructor_t create)
+{
+       u_int speed = 0;
+
+       if (!this->test_on_add ||
+               this->tester->test_xof(this->tester, algo, create,
+                                                          this->bench ? &speed : NULL, plugin_name))
+       {
+               add_entry(this, this->xofs, algo, plugin_name, speed, create);
+               return TRUE;
+       }
+       this->test_failures++;
+       return FALSE;
+}
+
+METHOD(crypto_factory_t, remove_xof, void,
+       private_crypto_factory_t *this, xof_constructor_t create)
+{
+       entry_t *entry;
+       enumerator_t *enumerator;
+
+       this->lock->write_lock(this->lock);
+       enumerator = this->xofs->create_enumerator(this->xofs);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create_xof == create)
+               {
+                       this->xofs->remove_at(this->xofs, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+}
+
 METHOD(crypto_factory_t, add_rng, bool,
        private_crypto_factory_t *this, rng_quality_t quality,
        const char *plugin_name, rng_constructor_t create)
@@ -846,6 +922,23 @@ METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
 }
 
 /**
+ * Filter function to enumerate algorithm, not entry
+ */
+static bool xof_filter(void *n, entry_t **entry, ext_out_function_t *algo,
+                                          void *i2, const char **plugin_name)
+{
+       *algo = (*entry)->algo;
+       *plugin_name = (*entry)->plugin_name;
+       return TRUE;
+}
+
+METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
+       private_crypto_factory_t *this)
+{
+       return create_enumerator(this, this->xofs, xof_filter);
+}
+
+/**
  * Filter function to enumerate group, not entry
  */
 static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group,
@@ -909,6 +1002,8 @@ METHOD(crypto_factory_t, add_test_vector, void,
                        return this->tester->add_hasher_vector(this->tester, vector);
                case PSEUDO_RANDOM_FUNCTION:
                        return this->tester->add_prf_vector(this->tester, vector);
+               case EXTENDED_OUTPUT_FUNCTION:
+                       return this->tester->add_xof_vector(this->tester, vector);
                case RANDOM_NUMBER_GENERATOR:
                        return this->tester->add_rng_vector(this->tester, vector);
                case DIFFIE_HELLMAN_GROUP:
@@ -961,6 +1056,10 @@ METHOD(enumerator_t, verify_enumerate, bool,
                        *valid = this->tester->test_prf(this->tester, entry->algo,
                                                        entry->create_prf, NULL, entry->plugin_name);
                        break;
+               case EXTENDED_OUTPUT_FUNCTION:
+                       *valid = this->tester->test_xof(this->tester, entry->algo,
+                                                       entry->create_xof, NULL, entry->plugin_name);
+                       break;
                case RANDOM_NUMBER_GENERATOR:
                        *valid = this->tester->test_rng(this->tester, entry->algo,
                                                        entry->create_rng, NULL, entry->plugin_name);
@@ -1009,6 +1108,9 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*,
                case PSEUDO_RANDOM_FUNCTION:
                        inner = this->prfs->create_enumerator(this->prfs);
                        break;
+               case EXTENDED_OUTPUT_FUNCTION:
+                       inner = this->xofs->create_enumerator(this->xofs);
+                       break;
                case RANDOM_NUMBER_GENERATOR:
                        inner = this->rngs->create_enumerator(this->rngs);
                        break;
@@ -1040,6 +1142,7 @@ METHOD(crypto_factory_t, destroy, void,
        this->signers->destroy(this->signers);
        this->hashers->destroy(this->hashers);
        this->prfs->destroy(this->prfs);
+       this->xofs->destroy(this->xofs);
        this->rngs->destroy(this->rngs);
        this->nonce_gens->destroy(this->nonce_gens);
        this->dhs->destroy(this->dhs);
@@ -1062,6 +1165,7 @@ crypto_factory_t *crypto_factory_create()
                        .create_signer = _create_signer,
                        .create_hasher = _create_hasher,
                        .create_prf = _create_prf,
+                       .create_xof = _create_xof,
                        .create_rng = _create_rng,
                        .create_nonce_gen = _create_nonce_gen,
                        .create_dh = _create_dh,
@@ -1075,6 +1179,8 @@ crypto_factory_t *crypto_factory_create()
                        .remove_hasher = _remove_hasher,
                        .add_prf = _add_prf,
                        .remove_prf = _remove_prf,
+                       .add_xof = _add_xof,
+                       .remove_xof = _remove_xof,
                        .add_rng = _add_rng,
                        .remove_rng = _remove_rng,
                        .add_nonce_gen = _add_nonce_gen,
@@ -1086,6 +1192,7 @@ crypto_factory_t *crypto_factory_create()
                        .create_signer_enumerator = _create_signer_enumerator,
                        .create_hasher_enumerator = _create_hasher_enumerator,
                        .create_prf_enumerator = _create_prf_enumerator,
+                       .create_xof_enumerator = _create_xof_enumerator,
                        .create_dh_enumerator = _create_dh_enumerator,
                        .create_rng_enumerator = _create_rng_enumerator,
                        .create_nonce_gen_enumerator = _create_nonce_gen_enumerator,
@@ -1098,6 +1205,7 @@ crypto_factory_t *crypto_factory_create()
                .signers = linked_list_create(),
                .hashers = linked_list_create(),
                .prfs = linked_list_create(),
+               .xofs = linked_list_create(),
                .rngs = linked_list_create(),
                .nonce_gens = linked_list_create(),
                .dhs = linked_list_create(),
index e039156..4f61ba1 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR 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
@@ -31,6 +32,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/xofs/xof.h>
 #include <crypto/nonce_gen.h>
 #include <crypto/diffie_hellman.h>
 #include <crypto/transform.h>
@@ -63,6 +65,11 @@ typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo);
 typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
 
 /**
+ * Constructor function for pseudo random functions
+ */
+typedef xof_t* (*xof_constructor_t)(ext_out_function_t algo);
+
+/**
  * Constructor function for source of randomness
  */
 typedef rng_t* (*rng_constructor_t)(rng_quality_t quality);
@@ -133,6 +140,14 @@ struct crypto_factory_t {
        prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo);
 
        /**
+        * Create an extended output function instance.
+        *
+        * @param algo                  XOF algorithm to use
+        * @return                              xof_t instance, NULL if not supported
+        */
+       xof_t* (*create_xof)(crypto_factory_t *this, ext_out_function_t algo);
+
+       /**
         * Create a source of randomness.
         *
         * @param quality               required randomness quality
@@ -253,6 +268,24 @@ struct crypto_factory_t {
        void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create);
 
        /**
+        * Register an xof 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_xof)(crypto_factory_t *this, ext_out_function_t algo,
+                                       const char *plugin_name, xof_constructor_t create);
+
+       /**
+        * Unregister an xof constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_xof)(crypto_factory_t *this, xof_constructor_t create);
+
+       /**
         * Register a source of randomness.
         *
         * @param quality               quality of randomness this RNG serves
@@ -342,6 +375,13 @@ struct crypto_factory_t {
        enumerator_t* (*create_prf_enumerator)(crypto_factory_t *this);
 
        /**
+        * Create an enumerator over all registered XOFs.
+        *
+        * @return                              enumerator over ext_out_function_t, plugin
+        */
+       enumerator_t* (*create_xof_enumerator)(crypto_factory_t *this);
+
+       /**
         * Create an enumerator over all registered diffie hellman groups.
         *
         * @return                              enumerator over diffie_hellman_group_t, plugin
index 5607d35..e86e7ae 100644 (file)
@@ -63,6 +63,11 @@ struct private_crypto_tester_t {
        linked_list_t *prf;
 
        /**
+        * List of XOF test vectors
+        */
+       linked_list_t *xof;
+
+       /**
         * List of RNG test vectors
         */
        linked_list_t *rng;
@@ -1035,6 +1040,146 @@ failure:
 }
 
 /**
+ * Benchmark an XOF
+ */
+static u_int bench_xof(private_crypto_tester_t *this,
+                                          ext_out_function_t alg, xof_constructor_t create)
+{
+       xof_t *xof;
+
+       xof = create(alg);
+       if (xof)
+       {
+               char seed[xof->get_seed_size(xof)];
+               char bytes[xof->get_block_size(xof)];
+               struct timespec start;
+               u_int runs;
+
+               memset(seed, 0x56, xof->get_seed_size(xof));
+               if (!xof->set_seed(xof, chunk_create(seed, xof->get_seed_size(xof))))
+               {
+                       xof->destroy(xof);
+                       return 0;
+               }
+
+               runs = 0;
+               start_timing(&start);
+               while (end_timing(&start) < this->bench_time)
+               {
+                       if (xof->get_bytes(xof, xof->get_block_size(xof), bytes))
+                       {
+                               runs++;
+                       }
+               }
+               xof->destroy(xof);
+
+               return runs;
+       }
+       return 0;
+}
+
+METHOD(crypto_tester_t, test_xof, bool,
+       private_crypto_tester_t *this, ext_out_function_t alg,
+       xof_constructor_t create, u_int *speed, const char *plugin_name)
+{
+       enumerator_t *enumerator;
+       xof_test_vector_t *vector;
+       bool failed = FALSE;
+       u_int tested = 0;
+
+       enumerator = this->xof->create_enumerator(this->xof);
+       while (enumerator->enumerate(enumerator, &vector))
+       {
+               xof_t *xof;
+               chunk_t seed, out = chunk_empty;
+
+               if (vector->alg != alg)
+               {
+                       continue;
+               }
+
+               tested++;
+               failed = TRUE;
+               xof = create(alg);
+               if (!xof)
+               {
+                       DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
+                                ext_out_function_names, alg, plugin_name);
+                       break;
+               }
+
+               seed = chunk_create(vector->seed, vector->len);
+               if (!xof->set_seed(xof, seed))
+               {
+                       goto failure;
+               }
+               /* allocated bytes */
+               if (!xof->allocate_bytes(xof, vector->out_len, &out))
+               {
+                       goto failure;
+               }
+               if (out.len != vector->out_len)
+               {
+                       goto failure;
+               }
+               if (!memeq(vector->out, out.ptr, out.len))
+               {
+                       goto failure;
+               }
+               /* bytes to existing buffer */
+               memset(out.ptr, 0, out.len);
+               if (!xof->set_seed(xof, seed))
+               {
+                       goto failure;
+               }
+               if (!xof->get_bytes(xof, vector->out_len, out.ptr))
+               {
+                       goto failure;
+               }
+               if (!memeq(vector->out, out.ptr, vector->out_len))
+               {
+                       goto failure;
+               }
+               /* bytes to existing buffer, using append mode */
+               /* TODO */
+
+               failed = FALSE;
+failure:
+               xof->destroy(xof);
+               chunk_free(&out);
+               if (failed)
+               {
+                       DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
+                                ext_out_function_names, alg, plugin_name, get_name(vector));
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       if (!tested)
+       {
+               DBG1(DBG_LIB, "%s %N[%s]: no test vectors found",
+                        this->required ? "disabled" : "enabled ",
+                        ext_out_function_names, alg, plugin_name);
+               return !this->required;
+       }
+       if (!failed)
+       {
+               if (speed)
+               {
+                       *speed = bench_xof(this, alg, create);
+                       DBG1(DBG_LIB, "enabled  %N[%s]: passed %u test vectors, %d points",
+                                ext_out_function_names, alg, plugin_name, tested, *speed);
+               }
+               else
+               {
+                       DBG1(DBG_LIB, "enabled  %N[%s]: passed %u test vectors",
+                                ext_out_function_names, alg, plugin_name, tested);
+               }
+       }
+       return !failed;
+}
+
+/**
  * Benchmark a RNG
  */
 static u_int bench_rng(private_crypto_tester_t *this,
@@ -1338,6 +1483,12 @@ METHOD(crypto_tester_t, add_prf_vector, void,
        this->prf->insert_last(this->prf, vector);
 }
 
+METHOD(crypto_tester_t, add_xof_vector, void,
+       private_crypto_tester_t *this, xof_test_vector_t *vector)
+{
+       this->xof->insert_last(this->xof, vector);
+}
+
 METHOD(crypto_tester_t, add_rng_vector, void,
        private_crypto_tester_t *this, rng_test_vector_t *vector)
 {
@@ -1358,6 +1509,7 @@ METHOD(crypto_tester_t, destroy, void,
        this->signer->destroy(this->signer);
        this->hasher->destroy(this->hasher);
        this->prf->destroy(this->prf);
+       this->xof->destroy(this->xof);
        this->rng->destroy(this->rng);
        this->dh->destroy(this->dh);
        free(this);
@@ -1377,6 +1529,7 @@ crypto_tester_t *crypto_tester_create()
                        .test_signer = _test_signer,
                        .test_hasher = _test_hasher,
                        .test_prf = _test_prf,
+                       .test_xof = _test_xof,
                        .test_rng = _test_rng,
                        .test_dh = _test_dh,
                        .add_crypter_vector = _add_crypter_vector,
@@ -1384,6 +1537,7 @@ crypto_tester_t *crypto_tester_create()
                        .add_signer_vector = _add_signer_vector,
                        .add_hasher_vector = _add_hasher_vector,
                        .add_prf_vector = _add_prf_vector,
+                       .add_xof_vector = _add_xof_vector,
                        .add_rng_vector = _add_rng_vector,
                        .add_dh_vector = _add_dh_vector,
                        .destroy = _destroy,
@@ -1393,6 +1547,7 @@ crypto_tester_t *crypto_tester_create()
                .signer = linked_list_create(),
                .hasher = linked_list_create(),
                .prf = linked_list_create(),
+               .xof = linked_list_create(),
                .rng = linked_list_create(),
                .dh = linked_list_create(),
 
index 6cc9b0d..34dfa94 100644 (file)
@@ -30,6 +30,7 @@ typedef struct aead_test_vector_t aead_test_vector_t;
 typedef struct signer_test_vector_t signer_test_vector_t;
 typedef struct hasher_test_vector_t hasher_test_vector_t;
 typedef struct prf_test_vector_t prf_test_vector_t;
+typedef struct xof_test_vector_t xof_test_vector_t;
 typedef struct rng_test_vector_t rng_test_vector_t;
 typedef struct dh_test_vector_t dh_test_vector_t;
 
@@ -114,6 +115,19 @@ struct prf_test_vector_t {
        u_char *out;
 };
 
+struct xof_test_vector_t {
+       /** xof algorithm this test vector tests */
+       ext_out_function_t alg;
+       /** size of the seed data */
+       size_t len;
+       /** seed data */
+       u_char *seed;
+       /** size of the output */
+       size_t out_len;
+       /** expected output of size*/
+       u_char *out;
+};
+
 /**
  * Test vector for a RNG.
  *
@@ -217,6 +231,17 @@ struct crypto_tester_t {
                                         prf_constructor_t create,
                                         u_int *speed, const char *plugin_name);
        /**
+        * Test an XOF algorithm.
+        *
+        * @param alg                   algorithm to test
+        * @param create                constructor function for the XOF
+        * @param speed                 speed test result, NULL to omit
+        * @return                              TRUE if test passed
+        */
+       bool (*test_xof)(crypto_tester_t *this, ext_out_function_t alg,
+                                        xof_constructor_t create,
+                                        u_int *speed, const char *plugin_name);
+       /**
         * Test a RNG implementation.
         *
         * @param alg                   algorithm to test
@@ -275,6 +300,13 @@ struct crypto_tester_t {
        void (*add_prf_vector)(crypto_tester_t *this, prf_test_vector_t *vector);
 
        /**
+        * Add a test vector to test an XOF.
+        *
+        * @param vector                pointer to test vector
+        */
+       void (*add_xof_vector)(crypto_tester_t *this, xof_test_vector_t *vector);
+
+       /**
         * Add a test vector to test a RNG.
         *
         * @param vector                pointer to test vector
index 7c6678b..808cb99 100644 (file)
 #include <crypto/hashers/hasher.h>
 #include <crypto/rngs/rng.h>
 
-ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, COMPRESSION_ALGORITHM,
+ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, EXTENDED_OUTPUT_FUNCTION,
        "UNDEFINED_TRANSFORM_TYPE",
        "HASH_ALGORITHM",
        "RANDOM_NUMBER_GENERATOR",
        "AEAD_ALGORITHM",
-       "COMPRESSION_ALGORITHM");
-ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, COMPRESSION_ALGORITHM,
+       "COMPRESSION_ALGORITHM",
+       "EXTENDED OUTPUT FUNCTION");
+ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS,
+                                                               EXTENDED_OUTPUT_FUNCTION,
        "ENCRYPTION_ALGORITHM",
        "PSEUDO_RANDOM_FUNCTION",
        "INTEGRITY_ALGORITHM",
@@ -60,6 +62,8 @@ enum_name_t* transform_get_enum_names(transform_type_t type)
                        return diffie_hellman_group_names;
                case EXTENDED_SEQUENCE_NUMBERS:
                        return extended_sequence_numbers_names;
+               case EXTENDED_OUTPUT_FUNCTION:
+                       return ext_out_function_names;
                case UNDEFINED_TRANSFORM_TYPE:
                case COMPRESSION_ALGORITHM:
                        break;
index 0cb84f0..e043e60 100644 (file)
@@ -34,6 +34,7 @@ enum transform_type_t {
        RANDOM_NUMBER_GENERATOR = 243,
        AEAD_ALGORITHM = 244,
        COMPRESSION_ALGORITHM = 245,
+       EXTENDED_OUTPUT_FUNCTION = 246,
        ENCRYPTION_ALGORITHM = 1,
        PSEUDO_RANDOM_FUNCTION = 2,
        INTEGRITY_ALGORITHM = 3,
diff --git a/src/libstrongswan/crypto/xofs/xof.c b/src/libstrongswan/crypto/xofs/xof.c
new file mode 100644 (file)
index 0000000..5a78271
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR 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.
+ */
+
+#include "xof.h"
+
+ENUM(ext_out_function_names, XOF_UNDEFINED, XOF_MGF1_SHA512,
+       "XOF_UNDEFINED",
+       "XOF_SHAKE128",
+       "XOF_SHAKE256",
+       "XOF_MGF1_SHA1",
+       "XOF_MGF1_SHA256",
+       "XOF_MGF1_SHA512"
+);
+
diff --git a/src/libstrongswan/crypto/xofs/xof.h b/src/libstrongswan/crypto/xofs/xof.h
new file mode 100644 (file)
index 0000000..11ef086
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR 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 xof xof
+ * @{ @ingroup crypto
+ */
+
+#ifndef XOF_H_
+#define XOF_H_
+
+typedef enum ext_out_function_t ext_out_function_t;
+typedef struct xof_t xof_t;
+
+#include <library.h>
+
+/**
+ * Extendable Output Functions.
+ */
+enum ext_out_function_t {
+       XOF_UNDEFINED,
+       /** FIPS 202 */
+       XOF_SHAKE_128,
+       /** FIPS 202 */
+       XOF_SHAKE_256,
+       /** RFC 2437 PKCS#1 */
+       XOF_MGF1_SHA1,
+       /** RFC 2437 PKCS#1 */
+       XOF_MGF1_SHA256,
+       /** RFC 2437 PKCS#1 */
+       XOF_MGF1_SHA512,
+};
+
+/**
+ * enum name for ext_out_function_t.
+ */
+extern enum_name_t *ext_out_function_names;
+
+/**
+ * Generic interface for pseudo-random-functions.
+ */
+struct xof_t {
+
+       /**
+        * Generates pseudo random bytes and writes them in the buffer.
+        *
+        * @param out_len       number of output bytes requested
+        * @param buffer        pointer where the generated bytes will be written
+        * @return                      TRUE if bytes generated successfully
+        */
+       bool (*get_bytes)(xof_t *this, size_t out_len,
+                                         uint8_t *buffer) __attribute__((warn_unused_result));
+
+       /**
+        * Generates pseudo random bytes and allocate space for them.
+        *
+        * @param out_len       number of output bytes requested
+        * @param chunk         chunk which will hold generated bytes
+        * @return                      TRUE if bytes allocated and generated successfully
+        */
+       bool (*allocate_bytes)(xof_t *this, size_t out_len,
+                                                  chunk_t *chunk) __attribute__((warn_unused_result));
+
+       /**
+        * Get the output block size
+        *
+        * @return                      block size in bytes
+        */
+       size_t (*get_block_size)(xof_t *this);
+
+       /**
+        * Get the recommended minimum seed size
+        *
+        * @return                      seed size in bytes
+        */
+       size_t (*get_seed_size)(xof_t *this);
+
+       /**
+        * Set the key for this xof_t object.
+        *
+        * @param sed           seed to set
+        * @return                      TRUE if XOF initialized with seed successfully
+        */
+       bool (*set_seed)(xof_t *this,
+                                        chunk_t seed) __attribute__((warn_unused_result));
+
+       /**
+        * Destroys a xof object.
+        */
+       void (*destroy)(xof_t *this);
+};
+
+#endif /** XOF_H_ @}*/
index 4c92c41..39d86c8 100644 (file)
@@ -30,6 +30,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
        "SIGNER",
        "HASHER",
        "PRF",
+       "XOF",
        "DH",
        "RNG",
        "NONCE_GEN",
@@ -87,6 +88,9 @@ uint32_t plugin_feature_hash(plugin_feature_t *feature)
                case FEATURE_PRF:
                        data = chunk_from_thing(feature->arg.prf);
                        break;
+               case FEATURE_XOF:
+                       data = chunk_from_thing(feature->arg.xof);
+                       break;
                case FEATURE_DH:
                        data = chunk_from_thing(feature->arg.dh_group);
                        break;
@@ -160,6 +164,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
                                return a->arg.hasher == b->arg.hasher;
                        case FEATURE_PRF:
                                return a->arg.prf == b->arg.prf;
+                       case FEATURE_XOF:
+                               return a->arg.xof == b->arg.xof;
                        case FEATURE_DH:
                                return a->arg.dh_group == b->arg.dh_group;
                        case FEATURE_RNG:
@@ -218,6 +224,7 @@ bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b)
                        case FEATURE_SIGNER:
                        case FEATURE_HASHER:
                        case FEATURE_PRF:
+                       case FEATURE_XOF:
                        case FEATURE_DH:
                        case FEATURE_NONCE_GEN:
                        case FEATURE_RESOLVER:
@@ -305,6 +312,13 @@ char* plugin_feature_get_string(plugin_feature_t *feature)
                                return str;
                        }
                        break;
+               case FEATURE_XOF:
+                       if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+                                       ext_out_function_names, feature->arg.xof) > 0)
+                       {
+                               return str;
+                       }
+                       break;
                case FEATURE_DH:
                        if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
                                        diffie_hellman_group_names, feature->arg.dh_group) > 0)
@@ -465,6 +479,10 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
                        lib->crypto->add_prf(lib->crypto, feature->arg.prf,
                                                                name, reg->arg.reg.f);
                        break;
+               case FEATURE_XOF:
+                       lib->crypto->add_xof(lib->crypto, feature->arg.xof,
+                                                               name, reg->arg.reg.f);
+                       break;
                case FEATURE_DH:
                        lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
                                                                name, reg->arg.reg.f);
@@ -552,6 +570,9 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
                case FEATURE_PRF:
                        lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f);
                        break;
+               case FEATURE_XOF:
+                       lib->crypto->remove_xof(lib->crypto, reg->arg.reg.f);
+                       break;
                case FEATURE_DH:
                        lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
                        break;
index ee7808a..8cc6277 100644 (file)
@@ -110,6 +110,8 @@ struct plugin_feature_t {
                FEATURE_HASHER,
                /** prf_t */
                FEATURE_PRF,
+               /** xof_t */
+               FEATURE_XOF,
                /** diffie_hellman_t */
                FEATURE_DH,
                /** rng_t */
@@ -171,6 +173,8 @@ struct plugin_feature_t {
                integrity_algorithm_t signer;
                /** FEATURE_PRF */
                pseudo_random_function_t prf;
+               /** FEATURE_XOFF */
+               ext_out_function_t xof;
                /** FEATURE_HASHER */
                hash_algorithm_t hasher;
                /** FEATURE_DH */
@@ -278,6 +282,7 @@ struct plugin_feature_t {
 #define _PLUGIN_FEATURE_SIGNER(kind, alg)                                      __PLUGIN_FEATURE(kind, SIGNER, .signer = alg)
 #define _PLUGIN_FEATURE_HASHER(kind, alg)                                      __PLUGIN_FEATURE(kind, HASHER, .hasher = alg)
 #define _PLUGIN_FEATURE_PRF(kind, alg)                                         __PLUGIN_FEATURE(kind, PRF, .prf = alg)
+#define _PLUGIN_FEATURE_XOF(kind, alg)                                         __PLUGIN_FEATURE(kind, XOF, .xof = 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)
@@ -310,6 +315,7 @@ struct plugin_feature_t {
 #define _PLUGIN_FEATURE_REGISTER_SIGNER(type, f)                       __PLUGIN_FEATURE_REGISTER(type, f)
 #define _PLUGIN_FEATURE_REGISTER_HASHER(type, f)                       __PLUGIN_FEATURE_REGISTER(type, f)
 #define _PLUGIN_FEATURE_REGISTER_PRF(type, f)                          __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_XOF(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)
index 0505e2c..c4d7184 100644 (file)
@@ -24,6 +24,7 @@
 #define TEST_VECTOR_SIGNER(x) extern signer_test_vector_t x;
 #define TEST_VECTOR_HASHER(x) extern hasher_test_vector_t x;
 #define TEST_VECTOR_PRF(x) extern prf_test_vector_t x;
+#define TEST_VECTOR_XOF(x) extern xof_test_vector_t x;
 #define TEST_VECTOR_RNG(x) extern rng_test_vector_t x;
 #define TEST_VECTOR_DH(x) extern dh_test_vector_t x;
 
@@ -34,6 +35,7 @@
 #undef TEST_VECTOR_SIGNER
 #undef TEST_VECTOR_HASHER
 #undef TEST_VECTOR_PRF
+#undef TEST_VECTOR_XOF
 #undef TEST_VECTOR_RNG
 #undef TEST_VECTOR_DH
 
@@ -42,6 +44,7 @@
 #define TEST_VECTOR_SIGNER(x)
 #define TEST_VECTOR_HASHER(x)
 #define TEST_VECTOR_PRF(x)
+#define TEST_VECTOR_XOF(x)
 #define TEST_VECTOR_RNG(x)
 #define TEST_VECTOR_DH(x)
 
@@ -86,6 +89,14 @@ static prf_test_vector_t *prf[] = {
 #undef TEST_VECTOR_PRF
 #define TEST_VECTOR_PRF(x)
 
+#undef TEST_VECTOR_XOF
+#define TEST_VECTOR_XOF(x) &x,
+static xof_test_vector_t *xof[] = {
+#include "test_vectors.h"
+};
+#undef TEST_VECTOR_XOF
+#define TEST_VECTOR_XOF(x)
+
 #undef TEST_VECTOR_RNG
 #define TEST_VECTOR_RNG(x) &x,
 static rng_test_vector_t *rng[] = {
@@ -181,6 +192,11 @@ plugin_t *test_vectors_plugin_create()
                lib->crypto->add_test_vector(lib->crypto,
                                                                         PSEUDO_RANDOM_FUNCTION, prf[i]);
        }
+       for (i = 0; i < countof(xof); i++)
+       {
+               lib->crypto->add_test_vector(lib->crypto,
+                                                                        EXTENDED_OUTPUT_FUNCTION, xof[i]);
+       }
        for (i = 0; i < countof(rng); i++)
        {
                lib->crypto->add_test_vector(lib->crypto,