The speed of md5 and sha* hashes has lagged a bit in gnulib.
So to address that and to take advantage of the architecture
specific assembly used in libcrypto, the attached gnulib patch
allows projects to configure --with-openssl to use that if
available or fall back to the existing internal routines.

There should be no issue with licensing as this is
just making use of the libcrypto system library where available:
  http://www.openssl.org/support/faq.html#LEGAL2
  http://www.gnu.org/licenses/gpl-faq.html#SystemLibraryException

I tested this with coreutils, with openssl-1.0.0j on an i3-2310M
and get a nice performance boost of about 40%:

$ time src/sha1sum.old 
~/old_laptop/old_home/padraig/imgs/linux/Fedora-Live-Desktop-x86_64-20-Beta-5.iso
SHA1 (/home/padraig/Fedora-Live-Desktop-x86_64-20-Beta-5.iso) = 
3c27f7ed01965fd2b89e22128fd62dc51a3bef30
real    0m4.692s
user    0m4.499s
sys     0m0.162s

$ time src/sha1sum --tag ~/Fedora-Live-Desktop-x86_64-20-Beta-5.iso
SHA1 (/home/padraig/Fedora-Live-Desktop-x86_64-20-Beta-5.iso) = 
3c27f7ed01965fd2b89e22128fd62dc51a3bef30
real    0m2.685s
user    0m2.512s
sys     0m0.170s

$ time openssl sha1 
~/old_laptop/old_home/padraig/imgs/linux/Fedora-Live-Desktop-x86_64-20-Beta-5.iso
SHA1(/home/padraig/Fedora-Live-Desktop-x86_64-20-Beta-5.iso)= 
3c27f7ed01965fd2b89e22128fd62dc51a3bef30
real    0m2.697s
user    0m2.538s
sys     0m0.157s


To use this from coreutils I configure with --with-openssl
and add in the appropriate libs as follows.
Note since the new libs are required, then is one of the reasons
I didn't enable this by default.  A related question though
is I'd like coreutils to change the default to enable this by default.
What would be the best way to do that, while still allowing users
to --with-openssl=no

thanks,
Pádraig.

diff --git a/src/local.mk b/src/local.mk
index 1315e11..db3a2b7 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -293,6 +293,15 @@ src_stdbuf_LDADD += $(LIBICONV)
 src_timeout_LDADD += $(LIBICONV)
 src_truncate_LDADD += $(LIBICONV)

+# for libcrypto
+src_md5sum_LDADD += $(LIB_CRYPTO_MD5)
+src_sort_LDADD += $(LIB_CRYPTO_MD5)
+src_sha1sum_LDADD += $(LIB_CRYPTO_SHA1)
+src_sha224sum_LDADD += $(LIB_CRYPTO_SHA256)
+src_sha256sum_LDADD += $(LIB_CRYPTO_SHA256)
+src_sha384sum_LDADD += $(LIB_CRYPTO_SHA512)
+src_sha512sum_LDADD += $(LIB_CRYPTO_SHA512)
+
 # for canon_host
 src_pinky_LDADD += $(GETADDRINFO_LIB)
 src_who_LDADD += $(GETADDRINFO_LIB)
>From 2e86a3507b521f4280ad1faa9b2e8c0f63a45dd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Sat, 30 Nov 2013 05:19:32 +0000
Subject: [PATCH] md5, sha1, sha256, sha512: use openssl routines if available

--with-openssl the libcrypto md5, sha1, sha224, sha256, sha384, sha256
routines will be used if available.

* lib/gl_openssl.h: Provide wrappers for specified openssl hash.
* m4/gl-openssl.m4 (gl_CRYPTO_CHECK): New function to lookup libcrypto
in the standard system location.
* m4/sha1.m4: Call gl_CRYPTO_CHECK() for SHA1.
* m4/sha256.m4: Likewise with SHA256.
* m4/sha512.m4: Likewise with SHA512.
* m4/md5.m4: Likewise with MD5.
* lib/sha1.h: Include wrappers if HAVE_OPENSSL_SHA1.
* lib/sha256.h: Likewise with SHA256.
* lib/sha512.h: Likewise with SHA512.
* lib/md5.h: Likewise with MD5.
* lib/sha1.c: Exlude functionality if HAVE_OPENSSL_SHA1.
* lib/sha256.c: Likewise with SHA256.
* lib/sha512.c: Likewise with SHA512.
* lib/md5.c: Likewise with MD5.
* modules/crypto/sha1 (Link:): Add the new optional lib.
(Depends-on:): Add dependency on extern-inline.
* modules/crypto/sha256: Likewise.
* modules/crypto/sha512: Likewise.
* modules/crypto/md5: Likewise.
* modules/crypto/sha1-tests: Reference the lib here too.
* modules/crypto/md5-tests: Likewise.
* modules/crypto/gc-des-tests: Likewise.
* modules/crypto/gc-hmac-md5-tests: Likewise.
* modules/crypto/gc-hmac-sha1-tests: Likewise.
* modules/crypto/gc-hmac-sha256-tests: Likewise.
* modules/crypto/gc-hmac-sha512-tests: Likewise.
* modules/crypto/gc-md5-tests: Likewise.
* modules/crypto/gc-pbkdf2-sha1-tests: Likewise.
* modules/crypto/gc-sha1-tests: Likewise.
* modules/crypto/gc-tests: Likewise.
* modules/crypto/hmac-md5-tests: Likewise.
* modules/crypto/hmac-sha1-tests: Likewise.
* modules/crypto/hmac-sha256-tests: Likewise.
* modules/crypto/hmac-sha512-tests: Likewise.
---
 lib/gl_openssl.h                    |  116 +++++++++++++++++++++++++++++++++++
 lib/md5.c                           |    7 ++
 lib/md5.h                           |   20 +++++--
 lib/sha1.c                          |    7 ++
 lib/sha1.h                          |   21 +++++--
 lib/sha256.c                        |    7 ++
 lib/sha256.h                        |   30 ++++++---
 lib/sha512.c                        |    7 ++
 lib/sha512.h                        |   31 ++++++---
 m4/gl-openssl.m4                    |   37 +++++++++++
 m4/md5.m4                           |    6 +-
 m4/sha1.m4                          |    6 +-
 m4/sha256.m4                        |    6 +-
 m4/sha512.m4                        |    6 +-
 modules/crypto/gc-des-tests         |    1 +
 modules/crypto/gc-hmac-md5-tests    |    1 +
 modules/crypto/gc-hmac-sha1-tests   |    1 +
 modules/crypto/gc-hmac-sha256-tests |    1 +
 modules/crypto/gc-hmac-sha512-tests |    1 +
 modules/crypto/gc-md5-tests         |    1 +
 modules/crypto/gc-pbkdf2-sha1-tests |    1 +
 modules/crypto/gc-sha1-tests        |    1 +
 modules/crypto/gc-tests             |    1 +
 modules/crypto/hmac-md5-tests       |    1 +
 modules/crypto/hmac-sha1-tests      |    1 +
 modules/crypto/hmac-sha256-tests    |    1 +
 modules/crypto/hmac-sha512-tests    |    1 +
 modules/crypto/md5                  |    6 ++
 modules/crypto/md5-tests            |    1 +
 modules/crypto/sha1                 |    6 ++
 modules/crypto/sha1-tests           |    1 +
 modules/crypto/sha256               |    6 ++
 modules/crypto/sha512               |    6 ++
 33 files changed, 308 insertions(+), 38 deletions(-)
 create mode 100644 lib/gl_openssl.h
 create mode 100644 m4/gl-openssl.m4

diff --git a/lib/gl_openssl.h b/lib/gl_openssl.h
new file mode 100644
index 0000000..a2fc8c2
--- /dev/null
+++ b/lib/gl_openssl.h
@@ -0,0 +1,116 @@
+/* gl_openssl.h -- wrap openssl crypto hash routines in gnulib interface
+
+   Copyright (C) 2013 Free Software Foundation, Inc.
+
+   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/>.  */
+
+/* Written by Pádraig Brady */
+
+#ifndef GL_OPENSSL_NAME
+# error "Please define GL_OPENSSL_NAME to 1,5,256 etc."
+#endif
+
+#ifndef _GL_INLINE_HEADER_BEGIN
+# error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef GL_OPENSSL_INLINE
+# define GL_OPENSSL_INLINE _GL_INLINE
+#endif
+
+/* Concatenate two preprocessor tokens.  */
+#define _GLCRYPTO_CONCAT_(prefix, suffix) prefix##suffix
+#define _GLCRYPTO_CONCAT(prefix, suffix) _GLCRYPTO_CONCAT_ (prefix, suffix)
+
+#if GL_OPENSSL_NAME == 5
+# define OPENSSL_ALG md5
+#else
+# define OPENSSL_ALG _GLCRYPTO_CONCAT (sha, GL_OPENSSL_NAME)
+#endif
+
+/* Context type mappings.  */
+#if BASE_OPENSSL_TYPE != GL_OPENSSL_NAME
+# undef BASE_OPENSSL_TYPE
+# if GL_OPENSSL_NAME == 224
+#  define BASE_OPENSSL_TYPE 256
+# elif GL_OPENSSL_NAME == 384
+#  define BASE_OPENSSL_TYPE 512
+# endif
+# define md5_CTX MD5_CTX
+# define sha1_CTX SHA_CTX
+# define sha224_CTX SHA256_CTX
+# define sha224_ctx sha256_ctx
+# define sha256_CTX SHA256_CTX
+# define sha384_CTX SHA512_CTX
+# define sha384_ctx sha512_ctx
+# define sha512_CTX SHA512_CTX
+# undef _gl_CTX
+# undef _gl_ctx
+# define _gl_CTX _GLCRYPTO_CONCAT (OPENSSL_ALG, _CTX) /* openssl type.  */
+# define _gl_ctx _GLCRYPTO_CONCAT (OPENSSL_ALG, _ctx) /* gnulib type.  */
+
+struct _gl_ctx { _gl_CTX CTX; };
+#endif
+
+/* Function name mappings.  */
+#define md5_prefix MD5
+#define sha1_prefix SHA1
+#define sha224_prefix SHA224
+#define sha256_prefix SHA256
+#define sha384_prefix SHA384
+#define sha512_prefix SHA512
+#define _GLCRYPTO_PREFIX _GLCRYPTO_CONCAT (OPENSSL_ALG, _prefix)
+#define OPENSSL_FN(suffix) _GLCRYPTO_CONCAT (_GLCRYPTO_PREFIX, suffix)
+#define GL_CRYPTO_FN(suffix) _GLCRYPTO_CONCAT (OPENSSL_ALG, suffix)
+
+GL_OPENSSL_INLINE void
+GL_CRYPTO_FN(_init_ctx) (struct _gl_ctx *ctx)
+  { (void) OPENSSL_FN(_Init) ((_gl_CTX *) ctx); }
+
+/* These were never exposed by gnulib.  */
+#if ! (GL_OPENSSL_NAME == 224 || GL_OPENSSL_NAME == 384)
+GL_OPENSSL_INLINE void
+GL_CRYPTO_FN(_process_bytes) (const void *buf, size_t len, struct _gl_ctx *ctx)
+  { OPENSSL_FN(_Update) ((_gl_CTX *) ctx, buf, len); }
+
+GL_OPENSSL_INLINE void
+GL_CRYPTO_FN(_process_block) (const void *buf, size_t len, struct _gl_ctx *ctx)
+  { GL_CRYPTO_FN(_process_bytes) (buf, len, ctx); }
+#endif
+
+GL_OPENSSL_INLINE void*
+GL_CRYPTO_FN(_finish_ctx) (struct _gl_ctx *ctx, void *res)
+  { OPENSSL_FN(_Final) (res, (_gl_CTX *) ctx); return res; }
+
+GL_OPENSSL_INLINE void*
+GL_CRYPTO_FN(_buffer) (const char *buf, size_t len, void *res)
+  { return OPENSSL_FN() ((const unsigned char *)buf, len, res); }
+
+GL_OPENSSL_INLINE void*
+GL_CRYPTO_FN(_read_ctx) (const struct _gl_ctx *ctx, void *res)
+{
+  /* Assume any unprocessed bytes in ctx are not to be ignored.  */
+  _gl_CTX tmp_ctx = *(_gl_CTX *) ctx;
+  OPENSSL_FN(_Final) (res, &tmp_ctx);
+  return res;
+}
+
+/* Undef so we can include multiple times.  */
+#undef GL_CRYPTO_FN
+#undef OPENSSL_FN
+#undef _GLCRYPTO_PREFIX
+#undef OPENSSL_ALG
+#undef GL_OPENSSL_NAME
+
+_GL_INLINE_HEADER_END
diff --git a/lib/md5.c b/lib/md5.c
index c41538c..6a7c2f6 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -21,6 +21,9 @@
 
 #include <config.h>
 
+#if HAVE_OPENSSL_MD5
+# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
+#endif
 #include "md5.h"
 
 #include <stdalign.h>
@@ -61,6 +64,7 @@
 # error "invalid BLOCKSIZE"
 #endif
 
+#if ! HAVE_OPENSSL_MD5
 /* This array contains the bytes used to pad the buffer to the next
    64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
@@ -128,6 +132,7 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
 
   return md5_read_ctx (ctx, resbuf);
 }
+#endif
 
 /* Compute MD5 message digest for bytes read from STREAM.  The
    resulting message digest number will be written into the 16 bytes
@@ -202,6 +207,7 @@ process_partial_block:
   return 0;
 }
 
+#if ! HAVE_OPENSSL_MD5
 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -459,3 +465,4 @@ md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
   ctx->C = C;
   ctx->D = D;
 }
+#endif
diff --git a/lib/md5.h b/lib/md5.h
index 3786dc5..1ad82c2 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -23,6 +23,10 @@
 #include <stdio.h>
 #include <stdint.h>
 
+# if HAVE_OPENSSL_MD5
+#  include <openssl/md5.h>
+# endif
+
 #define MD5_DIGEST_SIZE 16
 #define MD5_BLOCK_SIZE 64
 
@@ -57,6 +61,10 @@
 extern "C" {
 # endif
 
+# if HAVE_OPENSSL_MD5
+#  define GL_OPENSSL_NAME 5
+#  include "gl_openssl.h"
+# else
 /* Structure to save state of computation between the single steps.  */
 struct md5_ctx
 {
@@ -106,11 +114,6 @@ extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW;
 extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW;
 
 
-/* Compute MD5 message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 16 bytes
-   beginning at RESBLOCK.  */
-extern int __md5_stream (FILE *stream, void *resblock) __THROW;
-
 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -118,6 +121,13 @@ extern int __md5_stream (FILE *stream, void *resblock) __THROW;
 extern void *__md5_buffer (const char *buffer, size_t len,
                            void *resblock) __THROW;
 
+# endif
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+extern int __md5_stream (FILE *stream, void *resblock) __THROW;
+
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/lib/sha1.c b/lib/sha1.c
index 9d7d447..6cf583c 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -23,6 +23,9 @@
 
 #include <config.h>
 
+#if HAVE_OPENSSL_SHA1
+# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
+#endif
 #include "sha1.h"
 
 #include <stdalign.h>
@@ -46,6 +49,7 @@
 # error "invalid BLOCKSIZE"
 #endif
 
+#if ! HAVE_OPENSSL_SHA1
 /* This array contains the bytes used to pad the buffer to the next
    64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
@@ -116,6 +120,7 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
 
   return sha1_read_ctx (ctx, resbuf);
 }
+#endif
 
 /* Compute SHA1 message digest for bytes read from STREAM.  The
    resulting message digest number will be written into the 16 bytes
@@ -190,6 +195,7 @@ sha1_stream (FILE *stream, void *resblock)
   return 0;
 }
 
+#if ! HAVE_OPENSSL_SHA1
 /* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -424,3 +430,4 @@ sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
       e = ctx->E += e;
     }
 }
+#endif
diff --git a/lib/sha1.h b/lib/sha1.h
index 4e9829b..1bed735 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -22,12 +22,20 @@
 # include <stdio.h>
 # include <stdint.h>
 
+# if HAVE_OPENSSL_SHA1
+#  include <openssl/sha.h>
+# endif
+
 # ifdef __cplusplus
 extern "C" {
 # endif
 
 #define SHA1_DIGEST_SIZE 20
 
+# if HAVE_OPENSSL_SHA1
+#  define GL_OPENSSL_NAME 1
+#  include "gl_openssl.h"
+# else
 /* Structure to save state of computation between the single steps.  */
 struct sha1_ctx
 {
@@ -42,7 +50,6 @@ struct sha1_ctx
   uint32_t buffer[32];
 };
 
-
 /* Initialize structure containing state of computation. */
 extern void sha1_init_ctx (struct sha1_ctx *ctx);
 
@@ -73,17 +80,19 @@ extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
 extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
 
 
-/* Compute SHA1 message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 20 bytes
-   beginning at RESBLOCK.  */
-extern int sha1_stream (FILE *stream, void *resblock);
-
 /* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
 extern void *sha1_buffer (const char *buffer, size_t len, void *resblock);
 
+# endif
+/* Compute SHA1 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 20 bytes
+   beginning at RESBLOCK.  */
+extern int sha1_stream (FILE *stream, void *resblock);
+
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/lib/sha256.c b/lib/sha256.c
index 4b2cee3..9d6912c 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -22,6 +22,9 @@
 
 #include <config.h>
 
+#if HAVE_OPENSSL_SHA256
+# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
+#endif
 #include "sha256.h"
 
 #include <stdalign.h>
@@ -45,6 +48,7 @@
 # error "invalid BLOCKSIZE"
 #endif
 
+#if ! HAVE_OPENSSL_SHA256
 /* This array contains the bytes used to pad the buffer to the next
    64-byte boundary.  */
 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
@@ -163,6 +167,7 @@ sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
   sha256_conclude_ctx (ctx);
   return sha224_read_ctx (ctx, resbuf);
 }
+#endif
 
 /* Compute SHA256 message digest for bytes read from STREAM.  The
    resulting message digest number will be written into the 32 bytes
@@ -308,6 +313,7 @@ sha224_stream (FILE *stream, void *resblock)
   return 0;
 }
 
+#if ! HAVE_OPENSSL_SHA256
 /* Compute SHA512 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -567,3 +573,4 @@ sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
       h = ctx->state[7] += h;
     }
 }
+#endif
diff --git a/lib/sha256.h b/lib/sha256.h
index 7e62522..6ee326b 100644
--- a/lib/sha256.h
+++ b/lib/sha256.h
@@ -21,10 +21,23 @@
 # include <stdio.h>
 # include <stdint.h>
 
+# if HAVE_OPENSSL_SHA256
+#  include <openssl/sha.h>
+# endif
+
 # ifdef __cplusplus
 extern "C" {
 # endif
 
+enum { SHA224_DIGEST_SIZE = 224 / 8 };
+enum { SHA256_DIGEST_SIZE = 256 / 8 };
+
+# if HAVE_OPENSSL_SHA256
+#  define GL_OPENSSL_NAME 224
+#  include "gl_openssl.h"
+#  define GL_OPENSSL_NAME 256
+#  include "gl_openssl.h"
+# else
 /* Structure to save state of computation between the single steps.  */
 struct sha256_ctx
 {
@@ -35,9 +48,6 @@ struct sha256_ctx
   uint32_t buffer[32];
 };
 
-enum { SHA224_DIGEST_SIZE = 224 / 8 };
-enum { SHA256_DIGEST_SIZE = 256 / 8 };
-
 /* Initialize structure containing state of computation. */
 extern void sha256_init_ctx (struct sha256_ctx *ctx);
 extern void sha224_init_ctx (struct sha256_ctx *ctx);
@@ -71,12 +81,6 @@ extern void *sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
 extern void *sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
 
 
-/* Compute SHA256 (SHA224) message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 32 (28) bytes
-   beginning at RESBLOCK.  */
-extern int sha256_stream (FILE *stream, void *resblock);
-extern int sha224_stream (FILE *stream, void *resblock);
-
 /* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -84,6 +88,14 @@ extern int sha224_stream (FILE *stream, void *resblock);
 extern void *sha256_buffer (const char *buffer, size_t len, void *resblock);
 extern void *sha224_buffer (const char *buffer, size_t len, void *resblock);
 
+# endif
+/* Compute SHA256 (SHA224) message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 32 (28) bytes
+   beginning at RESBLOCK.  */
+extern int sha256_stream (FILE *stream, void *resblock);
+extern int sha224_stream (FILE *stream, void *resblock);
+
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/lib/sha512.c b/lib/sha512.c
index 79f1125..8429bb9 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -22,6 +22,9 @@
 
 #include <config.h>
 
+#if HAVE_OPENSSL_SHA512
+# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
+#endif
 #include "sha512.h"
 
 #include <stdalign.h>
@@ -52,6 +55,7 @@
 # error "invalid BLOCKSIZE"
 #endif
 
+#if ! HAVE_OPENSSL_SHA512
 /* This array contains the bytes used to pad the buffer to the next
    128-byte boundary.  */
 static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ...  */ };
@@ -171,6 +175,7 @@ sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
   sha512_conclude_ctx (ctx);
   return sha384_read_ctx (ctx, resbuf);
 }
+#endif
 
 /* Compute SHA512 message digest for bytes read from STREAM.  The
    resulting message digest number will be written into the 64 bytes
@@ -316,6 +321,7 @@ sha384_stream (FILE *stream, void *resblock)
   return 0;
 }
 
+#if ! HAVE_OPENSSL_SHA512
 /* Compute SHA512 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -619,3 +625,4 @@ sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
       h = ctx->state[7] = u64plus (ctx->state[7], h);
     }
 }
+#endif
diff --git a/lib/sha512.h b/lib/sha512.h
index 2e78a5f..1de93da 100644
--- a/lib/sha512.h
+++ b/lib/sha512.h
@@ -19,13 +19,25 @@
 # define SHA512_H 1
 
 # include <stdio.h>
-
 # include "u64.h"
 
+# if HAVE_OPENSSL_SHA512
+#  include <openssl/sha.h>
+# endif
+
 # ifdef __cplusplus
 extern "C" {
 # endif
 
+enum { SHA384_DIGEST_SIZE = 384 / 8 };
+enum { SHA512_DIGEST_SIZE = 512 / 8 };
+
+# if HAVE_OPENSSL_SHA512
+#  define GL_OPENSSL_NAME 384
+#  include "gl_openssl.h"
+#  define GL_OPENSSL_NAME 512
+#  include "gl_openssl.h"
+# else
 /* Structure to save state of computation between the single steps.  */
 struct sha512_ctx
 {
@@ -36,9 +48,6 @@ struct sha512_ctx
   u64 buffer[32];
 };
 
-enum { SHA384_DIGEST_SIZE = 384 / 8 };
-enum { SHA512_DIGEST_SIZE = 512 / 8 };
-
 /* Initialize structure containing state of computation. */
 extern void sha512_init_ctx (struct sha512_ctx *ctx);
 extern void sha384_init_ctx (struct sha512_ctx *ctx);
@@ -75,12 +84,6 @@ extern void *sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
 extern void *sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
 
 
-/* Compute SHA512 (SHA384) message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 64 (48) bytes
-   beginning at RESBLOCK.  */
-extern int sha512_stream (FILE *stream, void *resblock);
-extern int sha384_stream (FILE *stream, void *resblock);
-
 /* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
@@ -88,6 +91,14 @@ extern int sha384_stream (FILE *stream, void *resblock);
 extern void *sha512_buffer (const char *buffer, size_t len, void *resblock);
 extern void *sha384_buffer (const char *buffer, size_t len, void *resblock);
 
+# endif
+/* Compute SHA512 (SHA384) message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 64 (48) bytes
+   beginning at RESBLOCK.  */
+extern int sha512_stream (FILE *stream, void *resblock);
+extern int sha384_stream (FILE *stream, void *resblock);
+
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/m4/gl-openssl.m4 b/m4/gl-openssl.m4
new file mode 100644
index 0000000..a0faecf
--- /dev/null
+++ b/m4/gl-openssl.m4
@@ -0,0 +1,37 @@
+# sha1.m4 serial 1
+dnl Copyright (C) 2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_CRYPTO_CHECK],
+[
+  AC_ARG_WITH([openssl],
+    [AS_HELP_STRING([--with-openssl],
+      [Use openssl md5 and sha* routines if available: default=no])],
+    [],
+    [with_openssl=no])
+
+  if test "x$1" = xMD5; then
+    ALG_header=md5.h
+  else
+    ALG_header=sha.h
+  fi
+
+  m4_pushdef([ALG],[$1])
+  LIB_CRYPTO_[]ALG=
+  AC_SUBST([LIB_CRYPTO_]ALG)
+  if test "x$with_openssl" != xno; then
+    AC_CHECK_LIB([crypto], [$1],
+      [AC_CHECK_HEADERS([openssl/$ALG_header],
+        [LIB_CRYPTO_[]ALG='-lcrypto'
+         AC_DEFINE([HAVE_OPENSSL_$1],[1],
+           [Define to 1 if libcrypto is used for $1])])])
+    if test "x$with_openssl" = xyes; then
+      if test "x$LIB_CRYPTO_[]ALG" = x; then
+        AC_MSG_WARN([openssl development library not found for $1])
+      fi
+    fi
+  fi
+  m4_popdef([ALG])
+])
diff --git a/m4/md5.m4 b/m4/md5.m4
index 0ad6f50..1d4d884 100644
--- a/m4/md5.m4
+++ b/m4/md5.m4
@@ -1,4 +1,4 @@
-# md5.m4 serial 13
+# md5.m4 serial 14
 dnl Copyright (C) 2002-2006, 2008-2013 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,5 +8,7 @@ AC_DEFUN([gl_MD5],
 [
   dnl Prerequisites of lib/md5.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_MD5 and LIB_CRYPTO_MD5
+  gl_CRYPTO_CHECK([MD5])
 ])
diff --git a/m4/sha1.m4 b/m4/sha1.m4
index 21c775e..e49ec44 100644
--- a/m4/sha1.m4
+++ b/m4/sha1.m4
@@ -1,4 +1,4 @@
-# sha1.m4 serial 11
+# sha1.m4 serial 12
 dnl Copyright (C) 2002-2006, 2008-2013 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,5 +8,7 @@ AC_DEFUN([gl_SHA1],
 [
   dnl Prerequisites of lib/sha1.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_SHA1 and LIB_CRYPTO_SHA1
+  gl_CRYPTO_CHECK([SHA1])
 ])
diff --git a/m4/sha256.m4 b/m4/sha256.m4
index cbbd17a..9255bd3 100644
--- a/m4/sha256.m4
+++ b/m4/sha256.m4
@@ -1,4 +1,4 @@
-# sha256.m4 serial 7
+# sha256.m4 serial 8
 dnl Copyright (C) 2005, 2008-2013 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,5 +8,7 @@ AC_DEFUN([gl_SHA256],
 [
   dnl Prerequisites of lib/sha256.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_SHA256 and LIB_CRYPTO_SHA256
+  gl_CRYPTO_CHECK([SHA256])
 ])
diff --git a/m4/sha512.m4 b/m4/sha512.m4
index f4a6bf1..fe7c88c 100644
--- a/m4/sha512.m4
+++ b/m4/sha512.m4
@@ -1,4 +1,4 @@
-# sha512.m4 serial 8
+# sha512.m4 serial 9
 dnl Copyright (C) 2005-2006, 2008-2013 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,5 +8,7 @@ AC_DEFUN([gl_SHA512],
 [
   dnl Prerequisites of lib/sha512.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_SHA512 and LIB_CRYPTO_SHA512
+  gl_CRYPTO_CHECK([SHA512])
 ])
diff --git a/modules/crypto/gc-des-tests b/modules/crypto/gc-des-tests
index e9851db..e7c1c37 100644
--- a/modules/crypto/gc-des-tests
+++ b/modules/crypto/gc-des-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-des
 check_PROGRAMS += test-gc-des
+test_gc_des_LDADD = $(LDADD) @LIB_CRYPTO_MD5@ @LIB_CRYPTO_SHA1@ @LIB_CRYPTO_SHA256@ @LIB_CRYPTO_SHA512@
diff --git a/modules/crypto/gc-hmac-md5-tests b/modules/crypto/gc-hmac-md5-tests
index 699ccf9..67db8ac 100644
--- a/modules/crypto/gc-hmac-md5-tests
+++ b/modules/crypto/gc-hmac-md5-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-hmac-md5
 check_PROGRAMS += test-gc-hmac-md5
+test_gc_hmac_md5_LDADD = $(LDADD) @LIB_CRYPTO_MD5@
diff --git a/modules/crypto/gc-hmac-sha1-tests b/modules/crypto/gc-hmac-sha1-tests
index 2795ee9..b40b321 100644
--- a/modules/crypto/gc-hmac-sha1-tests
+++ b/modules/crypto/gc-hmac-sha1-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-hmac-sha1
 check_PROGRAMS += test-gc-hmac-sha1
+test_gc_hmac_sha1_LDADD = $(LDADD) @LIB_CRYPTO_SHA1@
diff --git a/modules/crypto/gc-hmac-sha256-tests b/modules/crypto/gc-hmac-sha256-tests
index 55934e0..4a1a6cc 100644
--- a/modules/crypto/gc-hmac-sha256-tests
+++ b/modules/crypto/gc-hmac-sha256-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-hmac-sha256
 check_PROGRAMS += test-gc-hmac-sha256
+test_gc_hmac_sha256_LDADD = $(LDADD) @LIB_CRYPTO_SHA256@
diff --git a/modules/crypto/gc-hmac-sha512-tests b/modules/crypto/gc-hmac-sha512-tests
index cc434c5..0ff93c8 100644
--- a/modules/crypto/gc-hmac-sha512-tests
+++ b/modules/crypto/gc-hmac-sha512-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-hmac-sha512
 check_PROGRAMS += test-gc-hmac-sha512
+test_gc_hmac_sha512_LDADD = $(LDADD) @LIB_CRYPTO_SHA512@
diff --git a/modules/crypto/gc-md5-tests b/modules/crypto/gc-md5-tests
index a271971..6b45a73 100644
--- a/modules/crypto/gc-md5-tests
+++ b/modules/crypto/gc-md5-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-md5
 check_PROGRAMS += test-gc-md5
+test_gc_md5_LDADD = $(LDADD) @LIB_CRYPTO_MD5@
diff --git a/modules/crypto/gc-pbkdf2-sha1-tests b/modules/crypto/gc-pbkdf2-sha1-tests
index d0f79ba..6793886 100644
--- a/modules/crypto/gc-pbkdf2-sha1-tests
+++ b/modules/crypto/gc-pbkdf2-sha1-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-pbkdf2-sha1
 check_PROGRAMS += test-gc-pbkdf2-sha1
+test_gc_pbkdf2_sha1_LDADD = $(LDADD) @LIB_CRYPTO_SHA1@
diff --git a/modules/crypto/gc-sha1-tests b/modules/crypto/gc-sha1-tests
index e438aa2..a557675 100644
--- a/modules/crypto/gc-sha1-tests
+++ b/modules/crypto/gc-sha1-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc-sha1
 check_PROGRAMS += test-gc-sha1
+test_gc_sha1_LDADD = $(LDADD) @LIB_CRYPTO_SHA1@
diff --git a/modules/crypto/gc-tests b/modules/crypto/gc-tests
index 6ce252f..656492f 100644
--- a/modules/crypto/gc-tests
+++ b/modules/crypto/gc-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-gc
 check_PROGRAMS += test-gc
+test_gc_LDADD = $(LDADD) @LIB_CRYPTO_MD5@ @LIB_CRYPTO_SHA1@ @LIB_CRYPTO_SHA256@ @LIB_CRYPTO_SHA512@
diff --git a/modules/crypto/hmac-md5-tests b/modules/crypto/hmac-md5-tests
index 738ee51..014536b 100644
--- a/modules/crypto/hmac-md5-tests
+++ b/modules/crypto/hmac-md5-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-hmac-md5
 check_PROGRAMS += test-hmac-md5
+test_hmac_md5_LDADD = $(LDADD) @LIB_CRYPTO_MD5@
diff --git a/modules/crypto/hmac-sha1-tests b/modules/crypto/hmac-sha1-tests
index ddebc58..754e0c5 100644
--- a/modules/crypto/hmac-sha1-tests
+++ b/modules/crypto/hmac-sha1-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-hmac-sha1
 check_PROGRAMS += test-hmac-sha1
+test_hmac_sha1_LDADD = $(LDADD) @LIB_CRYPTO_SHA1@
diff --git a/modules/crypto/hmac-sha256-tests b/modules/crypto/hmac-sha256-tests
index 1337a05..2ebd8b9 100644
--- a/modules/crypto/hmac-sha256-tests
+++ b/modules/crypto/hmac-sha256-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-hmac-sha256
 check_PROGRAMS += test-hmac-sha256
+test_hmac_sha256_LDADD = $(LDADD) @LIB_CRYPTO_SHA256@
diff --git a/modules/crypto/hmac-sha512-tests b/modules/crypto/hmac-sha512-tests
index d10b705..1459290 100644
--- a/modules/crypto/hmac-sha512-tests
+++ b/modules/crypto/hmac-sha512-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-hmac-sha512
 check_PROGRAMS += test-hmac-sha512
+test_hmac_sha512_LDADD = $(LDADD) @LIB_CRYPTO_SHA512@
diff --git a/modules/crypto/md5 b/modules/crypto/md5
index 4ae0c57..3b843b1 100644
--- a/modules/crypto/md5
+++ b/modules/crypto/md5
@@ -2,11 +2,14 @@ Description:
 Compute MD5 checksum.
 
 Files:
+lib/gl_openssl.h
 lib/md5.h
 lib/md5.c
+m4/gl-openssl.m4
 m4/md5.m4
 
 Depends-on:
+extern-inline
 stdalign
 stdint
 
@@ -19,6 +22,9 @@ lib_SOURCES += md5.c
 Include:
 "md5.h"
 
+Link:
+$(LIB_CRYPTO_MD5)
+
 License:
 LGPLv2+
 
diff --git a/modules/crypto/md5-tests b/modules/crypto/md5-tests
index 94bc3e4..63767ba 100644
--- a/modules/crypto/md5-tests
+++ b/modules/crypto/md5-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-md5
 check_PROGRAMS += test-md5
+test_md5_LDADD = $(LDADD) @LIB_CRYPTO_MD5@
diff --git a/modules/crypto/sha1 b/modules/crypto/sha1
index 8d00f31..0086ea9 100644
--- a/modules/crypto/sha1
+++ b/modules/crypto/sha1
@@ -2,11 +2,14 @@ Description:
 Compute SHA1 checksum.
 
 Files:
+lib/gl_openssl.h
 lib/sha1.h
 lib/sha1.c
+m4/gl-openssl.m4
 m4/sha1.m4
 
 Depends-on:
+extern-inline
 stdalign
 stdint
 
@@ -19,6 +22,9 @@ lib_SOURCES += sha1.c
 Include:
 "sha1.h"
 
+Link:
+$(LIB_CRYPTO_SHA1)
+
 License:
 LGPLv2+
 
diff --git a/modules/crypto/sha1-tests b/modules/crypto/sha1-tests
index 6da04d6..36c7a6d 100644
--- a/modules/crypto/sha1-tests
+++ b/modules/crypto/sha1-tests
@@ -8,3 +8,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-sha1
 check_PROGRAMS += test-sha1
+test_sha1_LDADD = $(LDADD) @LIB_CRYPTO_SHA1@
diff --git a/modules/crypto/sha256 b/modules/crypto/sha256
index f3f1d64..70755df 100644
--- a/modules/crypto/sha256
+++ b/modules/crypto/sha256
@@ -2,11 +2,14 @@ Description:
 Compute SHA224 and SHA256 checksums.
 
 Files:
+lib/gl_openssl.h
 lib/sha256.h
 lib/sha256.c
+m4/gl-openssl.m4
 m4/sha256.m4
 
 Depends-on:
+extern-inline
 stdalign
 stdint
 
@@ -19,6 +22,9 @@ lib_SOURCES += sha256.c
 Include:
 "sha256.h"
 
+Link:
+$(LIB_CRYPTO_SHA256)
+
 License:
 LGPLv2+
 
diff --git a/modules/crypto/sha512 b/modules/crypto/sha512
index a5065c4..d504b0e 100644
--- a/modules/crypto/sha512
+++ b/modules/crypto/sha512
@@ -2,11 +2,14 @@ Description:
 Compute SHA384 and SHA512 checksums.
 
 Files:
+lib/gl_openssl.h
 lib/sha512.h
 lib/sha512.c
+m4/gl-openssl.m4
 m4/sha512.m4
 
 Depends-on:
+extern-inline
 stdalign
 stdint
 u64
@@ -20,6 +23,9 @@ lib_SOURCES += sha512.c
 Include:
 "sha512.h"
 
+Link:
+$(LIB_CRYPTO_SHA512)
+
 License:
 LGPLv2+
 
-- 
1.7.7.6

Reply via email to