Use centralized hasher names in openssl plugin
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_hmac.c
index fa88238..5d05425 100644 (file)
 
 #include "openssl_hmac.h"
 
 
 #include "openssl_hmac.h"
 
-typedef struct private_openssl_hmac_t private_openssl_hmac_t;
+#include <crypto/mac.h>
+#include <crypto/prfs/mac_prf.h>
+#include <crypto/signers/mac_signer.h>
+
+typedef struct private_mac_t private_mac_t;
 
 /**
 
 /**
- * Private data of a openssl_hmac_t object.
+ * Private data of a mac_t object.
  */
  */
-struct private_openssl_hmac_t {
+struct private_mac_t {
 
        /**
         * Public interface
         */
 
        /**
         * Public interface
         */
-       openssl_hmac_t public;
+       mac_t public;
 
        /**
         * Hasher to use
 
        /**
         * Hasher to use
@@ -61,110 +65,83 @@ struct private_openssl_hmac_t {
         * Current HMAC context
         */
        HMAC_CTX hmac;
         * Current HMAC context
         */
        HMAC_CTX hmac;
-
-       /**
-        * Key
-        */
-       chunk_t key;
 };
 
 };
 
-/**
- * Resets HMAC context
- */
-static void reset(private_openssl_hmac_t *this)
+METHOD(mac_t, set_key, bool,
+       private_mac_t *this, chunk_t key)
 {
 {
-       HMAC_Init_ex(&this->hmac, this->key.ptr, this->key.len, this->hasher, NULL);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+       return HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL);
+#else /* OPENSSL_VERSION_NUMBER < 1.0 */
+       HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL);
+       return TRUE;
+#endif
 }
 
 }
 
-METHOD(openssl_hmac_t, get_mac, void,
-       private_openssl_hmac_t *this, chunk_t data, u_int8_t *out)
+METHOD(mac_t, get_mac, bool,
+       private_mac_t *this, chunk_t data, u_int8_t *out)
 {
 {
-       if (out == NULL)
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+       if (!HMAC_Update(&this->hmac, data.ptr, data.len))
        {
        {
-               HMAC_Update(&this->hmac, data.ptr, data.len);
+               return FALSE;
        }
        }
-       else
+       if (out == NULL)
        {
        {
-               HMAC_Update(&this->hmac, data.ptr, data.len);
-               HMAC_Final(&this->hmac, out, NULL);
-               reset(this);
+               return TRUE;
        }
        }
-}
-
-METHOD(openssl_hmac_t, allocate_mac, void,
-       private_openssl_hmac_t *this, chunk_t data, chunk_t *out)
-{
-       if (out == NULL)
+       if (!HMAC_Final(&this->hmac, out, NULL))
        {
        {
-               get_mac(this, data, NULL);
+               return FALSE;
        }
        }
-       else
+#else /* OPENSSL_VERSION_NUMBER < 1.0 */
+       HMAC_Update(&this->hmac, data.ptr, data.len);
+       if (out == NULL)
        {
        {
-               *out = chunk_alloc(EVP_MD_size(this->hasher));
-               get_mac(this, data, out->ptr);
+               return TRUE;
        }
        }
+       HMAC_Final(&this->hmac, out, NULL);
+#endif
+       return set_key(this, chunk_empty);
 }
 
 }
 
-METHOD(openssl_hmac_t, get_block_size, size_t,
-       private_openssl_hmac_t *this)
+METHOD(mac_t, get_mac_size, size_t,
+       private_mac_t *this)
 {
        return EVP_MD_size(this->hasher);
 }
 
 {
        return EVP_MD_size(this->hasher);
 }
 
-METHOD(openssl_hmac_t, set_key, void,
-       private_openssl_hmac_t *this, chunk_t key)
-{
-       chunk_clear(&this->key);
-       this->key = chunk_clone(key);
-       reset(this);
-}
-
-METHOD(openssl_hmac_t, destroy, void,
-       private_openssl_hmac_t *this)
+METHOD(mac_t, destroy, void,
+       private_mac_t *this)
 {
        HMAC_CTX_cleanup(&this->hmac);
 {
        HMAC_CTX_cleanup(&this->hmac);
-       chunk_clear(&this->key);
        free(this);
 }
 
 /*
        free(this);
 }
 
 /*
- * Described in header
+ * Create an OpenSSL-backed implementation of the mac_t interface
  */
  */
-openssl_hmac_t *openssl_hmac_create(hash_algorithm_t algo)
+static mac_t *hmac_create(hash_algorithm_t algo)
 {
 {
-       private_openssl_hmac_t *this;
+       private_mac_t *this;
+       char *name;
+
+       name = enum_to_name(hash_algorithm_short_names, algo);
+       if (!name)
+       {
+               return NULL;
+       }
 
        INIT(this,
                .public = {
                        .get_mac = _get_mac,
 
        INIT(this,
                .public = {
                        .get_mac = _get_mac,
-                       .allocate_mac = _allocate_mac,
-                       .get_block_size = _get_block_size,
+                       .get_mac_size = _get_mac_size,
                        .set_key = _set_key,
                        .destroy = _destroy,
                },
                        .set_key = _set_key,
                        .destroy = _destroy,
                },
+               .hasher = EVP_get_digestbyname(name),
        );
 
        );
 
-       switch (algo)
-       {
-               case HASH_MD5:
-                       this->hasher = EVP_get_digestbyname("md5");
-                       break;
-               case HASH_SHA1:
-                       this->hasher = EVP_get_digestbyname("sha1");
-                       break;
-               case HASH_SHA256:
-                       this->hasher = EVP_get_digestbyname("sha256");
-                       break;
-               case HASH_SHA384:
-                       this->hasher = EVP_get_digestbyname("sha384");
-                       break;
-               case HASH_SHA512:
-                       this->hasher = EVP_get_digestbyname("sha512");
-                       break;
-               default:
-                       break;
-       }
-
        if (!this->hasher)
        {
                free(this);
        if (!this->hasher)
        {
                free(this);
@@ -172,6 +149,43 @@ openssl_hmac_t *openssl_hmac_create(hash_algorithm_t algo)
        }
 
        HMAC_CTX_init(&this->hmac);
        }
 
        HMAC_CTX_init(&this->hmac);
+       if (!set_key(this, chunk_empty))
+       {
+               destroy(this);
+               return NULL;
+       }
 
        return &this->public;
 }
 
        return &this->public;
 }
+
+/*
+ * Described in header
+ */
+prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo)
+{
+       mac_t *hmac;
+
+       hmac = hmac_create(hasher_algorithm_from_prf(algo));
+       if (hmac)
+       {
+               return mac_prf_create(hmac);
+       }
+       return NULL;
+}
+
+/*
+ * Described in header
+ */
+signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo)
+{
+       mac_t *hmac;
+       size_t trunc;
+
+       hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc));
+       if (hmac)
+       {
+               return mac_signer_create(hmac, trunc);
+       }
+       return NULL;
+}
+