Added support for AEAD algorithms to crypto factory
authorMartin Willi <martin@revosec.ch>
Wed, 18 Aug 2010 18:16:03 +0000 (20:16 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 19 Aug 2010 17:02:34 +0000 (19:02 +0200)
src/libstrongswan/crypto/crypto_factory.c
src/libstrongswan/crypto/crypto_factory.h
src/libstrongswan/crypto/transform.c
src/libstrongswan/crypto/transform.h

index 27a2b83..60cd148 100644 (file)
@@ -29,6 +29,7 @@ struct entry_t {
        /* constructor */
        union {
                crypter_constructor_t create_crypter;
+               aead_constructor_t create_aead;
                signer_constructor_t create_signer;
                hasher_constructor_t create_hasher;
                prf_constructor_t create_prf;
@@ -56,6 +57,11 @@ struct private_crypto_factory_t {
        linked_list_t *crypters;
 
        /**
+        * registered aead transforms, as entry_t
+        */
+       linked_list_t *aeads;
+
+       /**
         * registered signers, as entry_t
         */
        linked_list_t *signers;
@@ -138,6 +144,38 @@ METHOD(crypto_factory_t, create_crypter, crypter_t*,
        return crypter;
 }
 
+METHOD(crypto_factory_t, create_aead, aead_t*,
+       private_crypto_factory_t *this, encryption_algorithm_t algo,
+       size_t key_size)
+{
+       enumerator_t *enumerator;
+       entry_t *entry;
+       aead_t *aead = NULL;
+
+       this->lock->read_lock(this->lock);
+       enumerator = this->aeads->create_enumerator(this->aeads);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->algo == algo)
+               {
+                       if (this->test_on_create &&
+                               !this->tester->test_aead(this->tester, algo, key_size,
+                                                                                entry->create_aead, NULL))
+                       {
+                               continue;
+                       }
+                       aead = entry->create_aead(algo, key_size);
+                       if (aead)
+                       {
+                               break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+       return aead;
+}
+
 METHOD(crypto_factory_t, create_signer, signer_t*,
        private_crypto_factory_t *this, integrity_algorithm_t algo)
 {
@@ -372,6 +410,40 @@ METHOD(crypto_factory_t, remove_crypter, void,
        this->lock->unlock(this->lock);
 }
 
+METHOD(crypto_factory_t, add_aead, void,
+       private_crypto_factory_t *this, encryption_algorithm_t algo,
+       aead_constructor_t create)
+{
+       u_int speed = 0;
+
+       if (!this->test_on_add ||
+               this->tester->test_aead(this->tester, algo, 0, create,
+                                                                  this->bench ? &speed : NULL))
+       {
+               add_entry(this, this->aeads, algo, speed, create);
+       }
+}
+
+METHOD(crypto_factory_t, remove_aead, void,
+       private_crypto_factory_t *this, aead_constructor_t create)
+{
+       entry_t *entry;
+       enumerator_t *enumerator;
+
+       this->lock->write_lock(this->lock);
+       enumerator = this->aeads->create_enumerator(this->aeads);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->create_aead == create)
+               {
+                       this->aeads->remove_at(this->aeads, enumerator);
+                       free(entry);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+}
+
 METHOD(crypto_factory_t, add_signer, void,
        private_crypto_factory_t *this, integrity_algorithm_t algo,
        signer_constructor_t create)
@@ -586,6 +658,12 @@ METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*,
        return create_enumerator(this, this->crypters, crypter_filter);
 }
 
+METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*,
+       private_crypto_factory_t *this)
+{
+       return create_enumerator(this, this->aeads, crypter_filter);
+}
+
 /**
  * Filter function to enumerate algorithm, not entry
  */
@@ -653,6 +731,8 @@ METHOD(crypto_factory_t, add_test_vector, void,
        {
                case ENCRYPTION_ALGORITHM:
                        return this->tester->add_crypter_vector(this->tester, vector);
+               case AEAD_ALGORITHM:
+                       return this->tester->add_aead_vector(this->tester, vector);
                case INTEGRITY_ALGORITHM:
                        return this->tester->add_signer_vector(this->tester, vector);
                case HASH_ALGORITHM:
@@ -671,6 +751,7 @@ METHOD(crypto_factory_t, destroy, void,
        private_crypto_factory_t *this)
 {
        this->crypters->destroy(this->crypters);
+       this->aeads->destroy(this->aeads);
        this->signers->destroy(this->signers);
        this->hashers->destroy(this->hashers);
        this->prfs->destroy(this->prfs);
@@ -691,6 +772,7 @@ crypto_factory_t *crypto_factory_create()
        INIT(this,
                .public = {
                        .create_crypter = _create_crypter,
+                       .create_aead = _create_aead,
                        .create_signer = _create_signer,
                        .create_hasher = _create_hasher,
                        .create_prf = _create_prf,
@@ -698,6 +780,8 @@ crypto_factory_t *crypto_factory_create()
                        .create_dh = _create_dh,
                        .add_crypter = _add_crypter,
                        .remove_crypter = _remove_crypter,
+                       .add_aead = _add_aead,
+                       .remove_aead = _remove_aead,
                        .add_signer = _add_signer,
                        .remove_signer = _remove_signer,
                        .add_hasher = _add_hasher,
@@ -709,6 +793,7 @@ crypto_factory_t *crypto_factory_create()
                        .add_dh = _add_dh,
                        .remove_dh = _remove_dh,
                        .create_crypter_enumerator = _create_crypter_enumerator,
+                       .create_aead_enumerator = _create_aead_enumerator,
                        .create_signer_enumerator = _create_signer_enumerator,
                        .create_hasher_enumerator = _create_hasher_enumerator,
                        .create_prf_enumerator = _create_prf_enumerator,
@@ -717,6 +802,7 @@ crypto_factory_t *crypto_factory_create()
                        .destroy = _destroy,
                },
                .crypters = linked_list_create(),
+               .aeads = linked_list_create(),
                .signers = linked_list_create(),
                .hashers = linked_list_create(),
                .prfs = linked_list_create(),
index 5bb39a8..7fe43c7 100644 (file)
@@ -25,6 +25,7 @@ typedef struct crypto_factory_t crypto_factory_t;
 
 #include <library.h>
 #include <crypto/crypters/crypter.h>
+#include <crypto/aead.h>
 #include <crypto/signers/signer.h>
 #include <crypto/hashers/hasher.h>
 #include <crypto/prfs/prf.h>
@@ -38,6 +39,11 @@ typedef struct crypto_factory_t crypto_factory_t;
 typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo,
                                                                                        size_t key_size);
 /**
+ * Constructor function for aead transforms
+ */
+typedef aead_t* (*aead_constructor_t)(encryption_algorithm_t algo,
+                                                                         size_t key_size);
+/**
  * Constructor function for signers
  */
 typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo);
@@ -78,6 +84,16 @@ struct crypto_factory_t {
                                                                 encryption_algorithm_t algo, size_t key_size);
 
        /**
+        * Create a aead instance.
+        *
+        * @param algo                  encryption algorithm
+        * @param key_size              length of the key in bytes
+        * @return                              aead_t instance, NULL if not supported
+        */
+       aead_t* (*create_aead)(crypto_factory_t *this,
+                                                  encryption_algorithm_t algo, size_t key_size);
+
+       /**
         * Create a symmetric signer instance.
         *
         * @param algo                  MAC algorithm to use
@@ -137,6 +153,23 @@ struct crypto_factory_t {
        void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create);
 
        /**
+        * Unregister a aead constructor.
+        *
+        * @param create                constructor function to unregister
+        */
+       void (*remove_aead)(crypto_factory_t *this, aead_constructor_t create);
+
+       /**
+        * Register a aead constructor.
+        *
+        * @param algo                  algorithm to constructor
+        * @param create                constructor function for that algorithm
+        * @return
+        */
+       void (*add_aead)(crypto_factory_t *this, encryption_algorithm_t algo,
+                                        aead_constructor_t create);
+
+       /**
         * Register a signer constructor.
         *
         * @param algo                  algorithm to constructor
@@ -230,6 +263,13 @@ struct crypto_factory_t {
        enumerator_t* (*create_crypter_enumerator)(crypto_factory_t *this);
 
        /**
+        * Create an enumerator over all registered aead algorithms.
+        *
+        * @return                              enumerator over encryption_algorithm_t
+        */
+       enumerator_t* (*create_aead_enumerator)(crypto_factory_t *this);
+
+       /**
         * Create an enumerator over all registered signer algorithms.
         *
         * @return                              enumerator over integrity_algorithm_t
index af40f4d..cec90a6 100644 (file)
 
 #include <crypto/transform.h>
 
-ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, RANDOM_NUMBER_GENERATOR,
+ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, AEAD_ALGORITHM,
        "UNDEFINED_TRANSFORM_TYPE",
        "HASH_ALGORITHM",
-       "RANDOM_NUMBER_GENERATOR");
-ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, RANDOM_NUMBER_GENERATOR,
+       "RANDOM_NUMBER_GENERATOR",
+       "AEAD_ALGORITHM");
+ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, AEAD_ALGORITHM,
        "ENCRYPTION_ALGORITHM",
        "PSEUDO_RANDOM_FUNCTION",
        "INTEGRITY_ALGORITHM",
index d11700a..1a26601 100644 (file)
@@ -32,6 +32,7 @@ enum transform_type_t {
        UNDEFINED_TRANSFORM_TYPE = 241,
        HASH_ALGORITHM = 242,
        RANDOM_NUMBER_GENERATOR = 243,
+       AEAD_ALGORITHM = 244,
        ENCRYPTION_ALGORITHM = 1,
        PSEUDO_RANDOM_FUNCTION = 2,
        INTEGRITY_ALGORITHM = 3,