summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-10-01 06:41:10 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-10-01 06:50:35 +0200
commitf402f9b2d2358c2a09e8973fcf877c7de71cd308 (patch)
treed4eef5281f0fa338d17bea13a0cff752a64ec040
parentd56146522aaf03414a4d69f2c61d9f8845134411 (diff)
downloadgnutls-f402f9b2d2358c2a09e8973fcf877c7de71cd308.tar.gz
The hash_fast() and hmac_fast() functions can be registered as well to allow
backends with optimized (hw) implementations. In the nettle backend the different is one memory allocation less.
-rw-r--r--lib/crypto-backend.h6
-rw-r--r--lib/gnutls_cipher_int.h2
-rw-r--r--lib/gnutls_hash_int.c45
-rw-r--r--lib/gnutls_hash_int.h2
-rw-r--r--lib/gnutls_mpi.h2
-rw-r--r--lib/gnutls_pk.h2
-rw-r--r--lib/nettle/cipher.c2
-rw-r--r--lib/nettle/mac.c89
-rw-r--r--lib/nettle/mpi.c2
-rw-r--r--lib/nettle/pk.c2
-rw-r--r--lib/nettle/rnd.c2
-rw-r--r--libextra/Makefile.am2
-rw-r--r--libextra/fipsmd5.c206
-rw-r--r--libextra/gnutls_extra.c17
14 files changed, 109 insertions, 272 deletions
diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h
index 5be0dd9a50..d0ba265378 100644
--- a/lib/crypto-backend.h
+++ b/lib/crypto-backend.h
@@ -51,16 +51,18 @@
int (*hash) (void *ctx, const void *text, size_t textsize);
int (*output) (void *src_ctx, void *digest, size_t digestsize);
void (*deinit) (void *ctx);
+ int (*fast)(gnutls_mac_algorithm_t, const void *key, size_t keysize, const void *text, size_t textsize, void *digest);
} gnutls_crypto_mac_st;
typedef struct
{
- int (*init) (gnutls_mac_algorithm_t, void **ctx);
+ int (*init) (gnutls_digest_algorithm_t, void **ctx);
void (*reset) (void *ctx);
- int (*hash) (void *ctx, const void *text, size_t textsize);
+ int (*hash) (void *ctx, const void *src, size_t srcsize);
int (*copy) (void **dst_ctx, void *src_ctx);
int (*output) (void *src_ctx, void *digest, size_t digestsize);
void (*deinit) (void *ctx);
+ int (*fast)(gnutls_digest_algorithm_t, const void *src, size_t srcsize, void *digest);
} gnutls_crypto_digest_st;
typedef struct gnutls_crypto_rnd
diff --git a/lib/gnutls_cipher_int.h b/lib/gnutls_cipher_int.h
index 5988819567..bd2b68d215 100644
--- a/lib/gnutls_cipher_int.h
+++ b/lib/gnutls_cipher_int.h
@@ -27,7 +27,7 @@
#include <crypto-backend.h>
extern int crypto_cipher_prio;
-extern const gnutls_crypto_cipher_st _gnutls_cipher_ops;
+extern gnutls_crypto_cipher_st _gnutls_cipher_ops;
typedef int (*cipher_encrypt_func) (void *hd, const void *plaintext, size_t,
void *ciphertext, size_t);
diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c
index 9dd5b09e6e..a6f781a4dc 100644
--- a/lib/gnutls_hash_int.c
+++ b/lib/gnutls_hash_int.c
@@ -145,25 +145,30 @@ int
_gnutls_hash_fast (gnutls_digest_algorithm_t algorithm,
const void *text, size_t textlen, void *digest)
{
- digest_hd_st dig;
int ret;
+ const gnutls_crypto_digest_st *cc = NULL;
- ret = _gnutls_hash_init (&dig, algorithm);
- if (ret < 0)
+ /* check if a digest has been registered
+ */
+ cc = _gnutls_get_crypto_digest (algorithm);
+ if (cc != NULL)
{
- gnutls_assert ();
- return ret;
+ if (cc->fast (algorithm, text, textlen, digest) < 0)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_HASH_FAILED;
+ }
+
+ return 0;
}
- ret = _gnutls_hash (&dig, text, textlen);
+ ret = _gnutls_digest_ops.fast (algorithm, text, textlen, digest);
if (ret < 0)
{
gnutls_assert ();
- _gnutls_hash_deinit (&dig, NULL);
return ret;
}
- _gnutls_hash_deinit (&dig, digest);
return 0;
}
@@ -174,26 +179,32 @@ int
_gnutls_hmac_fast (gnutls_mac_algorithm_t algorithm, const void *key,
int keylen, const void *text, size_t textlen, void *digest)
{
- digest_hd_st dig;
int ret;
+ const gnutls_crypto_mac_st *cc = NULL;
- ret = _gnutls_hmac_init (&dig, algorithm, key, keylen);
- if (ret < 0)
+ /* check if a digest has been registered
+ */
+ cc = _gnutls_get_crypto_mac (algorithm);
+ if (cc != NULL)
{
- gnutls_assert ();
- return ret;
+ if (cc->fast (algorithm, key, keylen, text, textlen, digest) < 0)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_HASH_FAILED;
+ }
+
+ return 0;
}
- ret = _gnutls_hmac (&dig, text, textlen);
+ ret = _gnutls_mac_ops.fast (algorithm, key, keylen, text, textlen, digest);
if (ret < 0)
{
gnutls_assert ();
- _gnutls_hmac_deinit (&dig, NULL);
return ret;
}
- _gnutls_hmac_deinit (&dig, digest);
return 0;
+
}
int
@@ -210,7 +221,7 @@ _gnutls_hmac_init (digest_hd_st * dig, gnutls_mac_algorithm_t algorithm,
/* check if a digest has been registered
*/
cc = _gnutls_get_crypto_mac (algorithm);
- if (cc != NULL)
+ if (cc != NULL && cc->init != NULL)
{
if (cc->init (algorithm, &dig->handle) < 0)
{
diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h
index 91a4325793..9780fffd5b 100644
--- a/lib/gnutls_hash_int.h
+++ b/lib/gnutls_hash_int.h
@@ -34,7 +34,7 @@ extern int crypto_mac_prio;
extern gnutls_crypto_mac_st _gnutls_mac_ops;
extern int crypto_digest_prio;
-extern const gnutls_crypto_digest_st _gnutls_digest_ops;
+extern gnutls_crypto_digest_st _gnutls_digest_ops;
typedef int (*hash_func) (void *handle, const void *text, size_t size);
typedef int (*copy_func) (void **dst_ctx, void *src_ctx);
diff --git a/lib/gnutls_mpi.h b/lib/gnutls_mpi.h
index 433020bbfb..fec3134cd9 100644
--- a/lib/gnutls_mpi.h
+++ b/lib/gnutls_mpi.h
@@ -28,7 +28,7 @@
#include <crypto-backend.h>
extern int crypto_bigint_prio;
-extern const gnutls_crypto_bigint_st _gnutls_mpi_ops;
+extern gnutls_crypto_bigint_st _gnutls_mpi_ops;
bigint_t _gnutls_mpi_randomize (bigint_t, unsigned int bits,
gnutls_rnd_level_t level);
diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h
index e50240d855..6c192da471 100644
--- a/lib/gnutls_pk.h
+++ b/lib/gnutls_pk.h
@@ -24,7 +24,7 @@
#define GNUTLS_PK_H
extern int crypto_pk_prio;
-extern const gnutls_crypto_pk_st _gnutls_pk_ops;
+extern gnutls_crypto_pk_st _gnutls_pk_ops;
#define _gnutls_pk_encrypt( algo, ciphertext, plaintext, params) _gnutls_pk_ops.encrypt( algo, ciphertext, plaintext, params)
#define _gnutls_pk_decrypt( algo, ciphertext, plaintext, params) _gnutls_pk_ops.decrypt( algo, ciphertext, plaintext, params)
diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c
index aa421de716..014a54924c 100644
--- a/lib/nettle/cipher.c
+++ b/lib/nettle/cipher.c
@@ -342,7 +342,7 @@ wrap_nettle_cipher_close (void *h)
gnutls_free (h);
}
-const gnutls_crypto_cipher_st _gnutls_cipher_ops = {
+gnutls_crypto_cipher_st _gnutls_cipher_ops = {
.init = wrap_nettle_cipher_init,
.setiv = wrap_nettle_cipher_setiv,
.setkey = wrap_nettle_cipher_setkey,
diff --git a/lib/nettle/mac.c b/lib/nettle/mac.c
index 0d512ad981..36cded6835 100644
--- a/lib/nettle/mac.c
+++ b/lib/nettle/mac.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2008, 2010, 2011 Free Software Foundation, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -35,7 +35,7 @@ typedef void (*update_func) (void *, unsigned, const uint8_t *);
typedef void (*digest_func) (void *, unsigned, uint8_t *);
typedef void (*set_key_func) (void *, unsigned, const uint8_t *);
-static int wrap_nettle_hash_init (gnutls_mac_algorithm_t algo, void **_ctx);
+static int wrap_nettle_hash_init (gnutls_digest_algorithm_t algo, void **_ctx);
struct nettle_hash_ctx
{
@@ -83,20 +83,8 @@ struct nettle_hmac_ctx
size_t key_size;
};
-static int
-wrap_nettle_hmac_init (gnutls_mac_algorithm_t algo, void **_ctx)
+static int _hmac_ctx_init(gnutls_mac_algorithm_t algo, struct nettle_hmac_ctx *ctx)
{
- struct nettle_hmac_ctx *ctx;
-
- ctx = gnutls_calloc (1, sizeof (struct nettle_hmac_ctx));
- if (ctx == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- ctx->algo = algo;
-
switch (algo)
{
case GNUTLS_MAC_MD5:
@@ -145,6 +133,46 @@ wrap_nettle_hmac_init (gnutls_mac_algorithm_t algo, void **_ctx)
gnutls_assert ();
return GNUTLS_E_INVALID_REQUEST;
}
+
+ return 0;
+}
+
+static int wrap_nettle_hmac_fast(gnutls_mac_algorithm_t algo,
+ const void *key, size_t key_size, const void* text, size_t text_size,
+ void* digest)
+{
+ struct nettle_hmac_ctx ctx;
+ int ret;
+
+ ret = _hmac_ctx_init(algo, &ctx);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ctx.setkey (&ctx, key_size, key);
+ ctx.update (&ctx, text_size, text);
+ ctx.digest (&ctx, ctx.length, digest);
+
+ return 0;
+}
+
+static int
+wrap_nettle_hmac_init (gnutls_mac_algorithm_t algo, void **_ctx)
+{
+ struct nettle_hmac_ctx *ctx;
+ int ret;
+
+ ctx = gnutls_calloc (1, sizeof (struct nettle_hmac_ctx));
+ if (ctx == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ctx->algo = algo;
+
+ ret = _hmac_ctx_init(algo, ctx);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
*_ctx = ctx;
@@ -161,7 +189,7 @@ wrap_nettle_hmac_setkey (void *_ctx, const void *key, size_t keylen)
ctx->key = gnutls_malloc(keylen);
if (ctx->key == NULL)
- return GNUTLS_E_MEMORY_ERROR;
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
memcpy(ctx->key, key, keylen);
ctx->key_size = keylen;
@@ -237,7 +265,7 @@ wrap_nettle_hash_deinit (void *hd)
gnutls_free (hd);
}
-static int _ctx_init(struct nettle_hash_ctx *ctx, gnutls_mac_algorithm_t algo)
+static int _ctx_init(gnutls_digest_algorithm_t algo, struct nettle_hash_ctx *ctx)
{
switch (algo)
{
@@ -298,8 +326,25 @@ static int _ctx_init(struct nettle_hash_ctx *ctx, gnutls_mac_algorithm_t algo)
return 0;
}
+static int wrap_nettle_hash_fast(gnutls_digest_algorithm_t algo,
+ const void* text, size_t text_size,
+ void* digest)
+{
+ struct nettle_hash_ctx ctx;
+ int ret;
+
+ ret = _ctx_init(algo, &ctx);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ctx.update (&ctx, text_size, text);
+ ctx.digest (&ctx, ctx.length, digest);
+
+ return 0;
+}
+
static int
-wrap_nettle_hash_init (gnutls_mac_algorithm_t algo, void **_ctx)
+wrap_nettle_hash_init (gnutls_digest_algorithm_t algo, void **_ctx)
{
struct nettle_hash_ctx *ctx;
int ret;
@@ -313,7 +358,7 @@ wrap_nettle_hash_init (gnutls_mac_algorithm_t algo, void **_ctx)
ctx->algo = algo;
- if ((ret=_ctx_init( ctx, algo)) < 0)
+ if ((ret=_ctx_init( algo, ctx)) < 0)
{
gnutls_assert ();
return ret;
@@ -347,7 +392,7 @@ wrap_nettle_hash_reset (void *src_ctx)
struct nettle_hash_ctx *ctx;
ctx = src_ctx;
- _ctx_init(ctx->ctx_ptr, ctx->algo);
+ _ctx_init(ctx->algo, ctx->ctx_ptr);
}
static int
@@ -374,13 +419,15 @@ gnutls_crypto_mac_st _gnutls_mac_ops = {
.reset = wrap_nettle_hmac_reset,
.output = wrap_nettle_hmac_output,
.deinit = wrap_nettle_hmac_deinit,
+ .fast = wrap_nettle_hmac_fast,
};
-const gnutls_crypto_digest_st _gnutls_digest_ops = {
+gnutls_crypto_digest_st _gnutls_digest_ops = {
.init = wrap_nettle_hash_init,
.hash = wrap_nettle_hash_update,
.reset = wrap_nettle_hash_reset,
.copy = wrap_nettle_hash_copy,
.output = wrap_nettle_hash_output,
.deinit = wrap_nettle_hash_deinit,
+ .fast = wrap_nettle_hash_fast,
};
diff --git a/lib/nettle/mpi.c b/lib/nettle/mpi.c
index c43b209a7c..a09549e206 100644
--- a/lib/nettle/mpi.c
+++ b/lib/nettle/mpi.c
@@ -618,7 +618,7 @@ wrap_nettle_generate_group (gnutls_group_st * group, unsigned int bits)
int crypto_bigint_prio = INT_MAX;
-const gnutls_crypto_bigint_st _gnutls_mpi_ops = {
+gnutls_crypto_bigint_st _gnutls_mpi_ops = {
.bigint_new = wrap_nettle_mpi_new,
.bigint_cmp = wrap_nettle_mpi_cmp,
.bigint_cmp_ui = wrap_nettle_mpi_cmp_ui,
diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c
index 084a521e61..794a2c99be 100644
--- a/lib/nettle/pk.c
+++ b/lib/nettle/pk.c
@@ -881,7 +881,7 @@ wrap_nettle_pk_fixup (gnutls_pk_algorithm_t algo,
int crypto_pk_prio = INT_MAX;
-const gnutls_crypto_pk_st _gnutls_pk_ops = {
+gnutls_crypto_pk_st _gnutls_pk_ops = {
.encrypt = _wrap_nettle_pk_encrypt,
.decrypt = _wrap_nettle_pk_decrypt,
.sign = _wrap_nettle_pk_sign,
diff --git a/lib/nettle/rnd.c b/lib/nettle/rnd.c
index 142481dc73..b3e18ac1f6 100644
--- a/lib/nettle/rnd.c
+++ b/lib/nettle/rnd.c
@@ -468,7 +468,7 @@ wrap_nettle_rnd (void *_ctx, int level, void *data, size_t datasize)
int crypto_rnd_prio = INT_MAX;
-const gnutls_crypto_rnd_st _gnutls_rnd_ops = {
+gnutls_crypto_rnd_st _gnutls_rnd_ops = {
.init = wrap_nettle_rnd_init,
.deinit = wrap_nettle_rnd_deinit,
.rnd = wrap_nettle_rnd,
diff --git a/libextra/Makefile.am b/libextra/Makefile.am
index 6bfe0b88bc..31c2a95dba 100644
--- a/libextra/Makefile.am
+++ b/libextra/Makefile.am
@@ -47,7 +47,7 @@ defexec_DATA =
lib_LTLIBRARIES = libgnutls-extra.la
-libgnutls_extra_la_SOURCES = libgnutls-extra.map gnutls_extra.c fipsmd5.c
+libgnutls_extra_la_SOURCES = libgnutls-extra.map gnutls_extra.c
libgnutls_openssl_la_LDFLAGS = -no-undefined
diff --git a/libextra/fipsmd5.c b/libextra/fipsmd5.c
deleted file mode 100644
index 801289aadc..0000000000
--- a/libextra/fipsmd5.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2008, 2010 Free Software Foundation, Inc.
- *
- * Author: Simon Josefsson
- *
- * This file is part of GnuTLS-EXTRA.
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <gnutls_int.h>
-#include <gnutls/crypto.h>
-#include <gnutls/extra.h>
-
-#include <md5.h>
-#include <hmac.h>
-
-static int
-md5init (gnutls_mac_algorithm_t mac, void **ctx)
-{
- *ctx = gnutls_malloc (sizeof (struct md5_ctx));
- if (!*ctx)
- return GNUTLS_E_MEMORY_ERROR;
- md5_init_ctx (*ctx);
- return 0;
-}
-
-static int
-md5hash (void *ctx, const void *text, size_t textsize)
-{
- md5_process_bytes (text, textsize, ctx);
- return 0;
-}
-
-static int
-md5copy (void **dst_ctx, void *src_ctx)
-{
- *dst_ctx = gnutls_malloc (sizeof (struct md5_ctx));
- if (!*dst_ctx)
- return GNUTLS_E_MEMORY_ERROR;
- memcpy (*dst_ctx, src_ctx, sizeof (struct md5_ctx));
- return 0;
-}
-
-static int
-md5output (void *src_ctx, void *digest, size_t digestsize)
-{
- char out[MD5_DIGEST_SIZE];
- md5_finish_ctx (src_ctx, out);
- memcpy (digest, out, digestsize);
- return 0;
-}
-
-static void
-md5deinit (void *ctx)
-{
- gnutls_free (ctx);
-}
-
-struct hmacctx
-{
- char *data;
- size_t datasize;
- char *key;
- size_t keysize;
-};
-
-static int
-hmacmd5init (gnutls_mac_algorithm_t mac, void **ctx)
-{
- struct hmacctx *p;
-
- p = gnutls_malloc (sizeof (struct hmacctx));
- if (!p)
- return -1;
-
- p->data = NULL;
- p->datasize = 0;
- p->key = NULL;
- p->keysize = 0;
-
- *ctx = p;
-
- return 0;
-}
-
-static int
-hmacmd5setkey (void *ctx, const void *key, size_t keysize)
-{
- struct hmacctx *p = ctx;
-
- if (p->key)
- gnutls_free (p->key);
-
- p->key = gnutls_malloc (keysize);
- if (!p->key)
- return -1;
-
- memcpy (p->key, key, keysize);
- p->keysize = keysize;
-
- return 0;
-}
-
-static int
-hmacmd5hash (void *ctx, const void *text, size_t textsize)
-{
- struct hmacctx *p = ctx;
- char *new;
-
- new = gnutls_realloc (p->data, p->datasize + textsize);
- if (!new)
- return -1;
-
- memcpy (new + p->datasize, text, textsize);
-
- p->data = new;
- p->datasize += textsize;
-
- return 0;
-}
-
-static int
-hmacmd5output (void *ctx, void *digest, size_t digestsize)
-{
- struct hmacctx *p = ctx;
- char out[MD5_DIGEST_SIZE];
- int ret;
-
- ret = hmac_md5 (p->key, p->keysize, p->data, p->datasize, out);
- if (ret)
- return GNUTLS_E_HASH_FAILED;
-
- memcpy (digest, out, digestsize);
-
- return 0;
-}
-
-static void
-hmacmd5deinit (void *ctx)
-{
- struct hmacctx *p = ctx;
-
- if (p->data)
- gnutls_free (p->data);
- if (p->key)
- gnutls_free (p->key);
-
- gnutls_free (p);
-}
-
-static gnutls_crypto_digest_st dig = {
- .init = md5init,
- .hash = md5hash,
- .copy = md5copy,
- .output = md5output,
- .deinit = md5deinit
-};
-
-static gnutls_crypto_mac_st mac = {
- .init = hmacmd5init,
- .setkey = hmacmd5setkey,
- .hash = hmacmd5hash,
- .output = hmacmd5output,
- .deinit = hmacmd5deinit
-};
-
-/**
- * gnutls_register_md5_handler:
- *
- * Register a non-libgcrypt based MD5 and HMAC-MD5 handler. This is
- * useful if you run Libgcrypt in FIPS-mode. Normally TLS requires
- * use of MD5, so without this you cannot use GnuTLS with libgcrypt in
- * FIPS mode.
- *
- * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
- *
- * Since: 2.6.0
- **/
-int
-gnutls_register_md5_handler (void)
-{
- int ret;
-
- ret = gnutls_crypto_single_digest_register (GNUTLS_DIG_MD5, INT_MAX, &dig);
- if (ret)
- return ret;
-
- ret = gnutls_crypto_single_mac_register (GNUTLS_MAC_MD5, INT_MAX, &mac);
- if (ret)
- return ret;
-
- return 0;
-}
diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c
index 71d051a3ed..a7a4b8019a 100644
--- a/libextra/gnutls_extra.c
+++ b/libextra/gnutls_extra.c
@@ -66,23 +66,6 @@ gnutls_global_init_extra (void)
if (_gnutls_init_extra != 1)
return 0;
-#ifdef HAVE_GCRYPT
-#ifdef gcry_fips_mode_active
- /* Libgcrypt manual says that gcry_version_check must be called
- before calling gcry_fips_mode_active. */
- gcry_check_version (NULL);
- if (gcry_fips_mode_active ())
- {
- int ret;
-
- ret = gnutls_register_md5_handler ();
- if (ret)
- fprintf (stderr, "gnutls_register_md5_handler: %s\n",
- gnutls_strerror (ret));
- }
-#endif
-#endif
-
return 0;
}