diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-10-01 06:41:10 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-10-01 06:50:35 +0200 |
commit | f402f9b2d2358c2a09e8973fcf877c7de71cd308 (patch) | |
tree | d4eef5281f0fa338d17bea13a0cff752a64ec040 | |
parent | d56146522aaf03414a4d69f2c61d9f8845134411 (diff) | |
download | gnutls-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.h | 6 | ||||
-rw-r--r-- | lib/gnutls_cipher_int.h | 2 | ||||
-rw-r--r-- | lib/gnutls_hash_int.c | 45 | ||||
-rw-r--r-- | lib/gnutls_hash_int.h | 2 | ||||
-rw-r--r-- | lib/gnutls_mpi.h | 2 | ||||
-rw-r--r-- | lib/gnutls_pk.h | 2 | ||||
-rw-r--r-- | lib/nettle/cipher.c | 2 | ||||
-rw-r--r-- | lib/nettle/mac.c | 89 | ||||
-rw-r--r-- | lib/nettle/mpi.c | 2 | ||||
-rw-r--r-- | lib/nettle/pk.c | 2 | ||||
-rw-r--r-- | lib/nettle/rnd.c | 2 | ||||
-rw-r--r-- | libextra/Makefile.am | 2 | ||||
-rw-r--r-- | libextra/fipsmd5.c | 206 | ||||
-rw-r--r-- | libextra/gnutls_extra.c | 17 |
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; } |