aead: Support custom AEAD salt sizes
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_gcm.c
index fde7ae7..147e4af 100644 (file)
  * for more details.
  */
 
+#include <openssl/opensslv.h>
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL
+
 #include "openssl_gcm.h"
 
 #include <openssl/evp.h>
+#include <crypto/iv/iv_gen_seq.h>
 
 /** as defined in RFC 4106 */
 #define IV_LEN         8
@@ -50,6 +55,11 @@ struct private_aead_t {
        size_t icv_size;
 
        /**
+        * IV generator
+        */
+       iv_gen_t *iv_gen;
+
+       /**
         * The cipher to use
         */
        const EVP_CIPHER *cipher;
@@ -157,6 +167,12 @@ METHOD(aead_t, get_iv_size, size_t,
        return IV_LEN;
 }
 
+METHOD(aead_t, get_iv_gen, iv_gen_t*,
+       private_aead_t *this)
+{
+       return this->iv_gen;
+}
+
 METHOD(aead_t, get_key_size, size_t,
        private_aead_t *this)
 {
@@ -179,13 +195,15 @@ METHOD(aead_t, destroy, void,
        private_aead_t *this)
 {
        chunk_clear(&this->key);
+       this->iv_gen->destroy(this->iv_gen);
        free(this);
 }
 
 /*
  * Described in header
  */
-aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size)
+aead_t *openssl_gcm_create(encryption_algorithm_t algo,
+                                                  size_t key_size, size_t salt_size)
 {
        private_aead_t *this;
 
@@ -196,6 +214,7 @@ aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size)
                        .get_block_size = _get_block_size,
                        .get_icv_size = _get_icv_size,
                        .get_iv_size = _get_iv_size,
+                       .get_iv_gen = _get_iv_gen,
                        .get_key_size = _get_key_size,
                        .set_key = _set_key,
                        .destroy = _destroy,
@@ -218,6 +237,13 @@ aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size)
                        return NULL;
        }
 
+       if (salt_size && salt_size != SALT_LEN)
+       {
+               /* currently not supported */
+               free(this);
+               return NULL;
+       }
+
        switch (algo)
        {
                case ENCR_AES_GCM_ICV8:
@@ -254,6 +280,9 @@ aead_t *openssl_gcm_create(encryption_algorithm_t algo, size_t key_size)
        }
 
        this->key = chunk_alloc(key_size);
+       this->iv_gen = iv_gen_seq_create();
 
        return &this->public;
 }
+
+#endif /* OPENSSL_VERSION_NUMBER */