changeset 37245:135e82dafbea

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, requiring apps to link @LIB_CRYPTO@ * 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. * m4/gc.m4: Ensure @LIB_CRYPTO@ set for tests. * 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.
author Pádraig Brady <P@draigBrady.com>
date Sat, 30 Nov 2013 05:19:32 +0000
parents 1ded04c3e4bb
children 5cfb3a67238d
files ChangeLog lib/gl_openssl.h lib/md5.c lib/md5.h lib/sha1.c lib/sha1.h lib/sha256.c lib/sha256.h lib/sha512.c lib/sha512.h m4/gc.m4 m4/gl-openssl.m4 m4/md5.m4 m4/sha1.m4 m4/sha256.m4 m4/sha512.m4 modules/crypto/gc-des-tests modules/crypto/gc-hmac-md5-tests modules/crypto/gc-hmac-sha1-tests modules/crypto/gc-hmac-sha256-tests modules/crypto/gc-hmac-sha512-tests modules/crypto/gc-md5-tests modules/crypto/gc-pbkdf2-sha1-tests modules/crypto/gc-sha1-tests modules/crypto/gc-tests modules/crypto/hmac-md5-tests modules/crypto/hmac-sha1-tests modules/crypto/hmac-sha256-tests modules/crypto/hmac-sha512-tests modules/crypto/md5 modules/crypto/md5-tests modules/crypto/sha1 modules/crypto/sha1-tests modules/crypto/sha256 modules/crypto/sha512
diffstat 35 files changed, 350 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Nov 29 15:35:33 2013 +0000
+++ b/ChangeLog	Sat Nov 30 05:19:32 2013 +0000
@@ -1,3 +1,45 @@
+2013-12-02  Pádraig Brady <P@draigBrady.com>
+
+	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, requiring apps to link @LIB_CRYPTO@
+	* 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.
+	* m4/gc.m4: Ensure @LIB_CRYPTO@ set for tests.
+	* 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.
+
 2013-11-29  RV1971  <rv1971@web.de>
 
 	base64: (trivial) fix compilation regression on some compilers
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/gl_openssl.h	Sat Nov 30 05:19:32 2013 +0000
@@ -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
--- a/lib/md5.c	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/md5.c	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
 
   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 @@
   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 @@
   ctx->C = C;
   ctx->D = D;
 }
+#endif
--- a/lib/md5.h	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/md5.h	Sat Nov 30 05:19:32 2013 +0000
@@ -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_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 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
--- a/lib/sha1.c	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/sha1.c	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
 
   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 @@
   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 @@
       e = ctx->E += e;
     }
 }
+#endif
--- a/lib/sha1.h	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/sha1.h	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
   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_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
--- a/lib/sha256.c	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/sha256.c	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
   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 @@
   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 @@
       h = ctx->state[7] += h;
     }
 }
+#endif
--- a/lib/sha256.h	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/sha256.h	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
   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 *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 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
--- a/lib/sha512.c	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/sha512.c	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
   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 @@
   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 @@
       h = ctx->state[7] = u64plus (ctx->state[7], h);
     }
 }
+#endif
--- a/lib/sha512.h	Fri Nov 29 15:35:33 2013 +0000
+++ b/lib/sha512.h	Sat Nov 30 05:19:32 2013 +0000
@@ -19,13 +19,25 @@
 # define SHA512_H 1
 
 # include <stdio.h>
+# include "u64.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 @@
   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 *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 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
--- a/m4/gc.m4	Fri Nov 29 15:35:33 2013 +0000
+++ b/m4/gc.m4	Sat Nov 30 05:19:32 2013 +0000
@@ -6,6 +6,8 @@
 
 AC_DEFUN([gl_GC],
 [
+  LIB_CRYPTO=
+  AC_SUBST([LIB_CRYPTO])
   AC_ARG_WITH([libgcrypt],
     AS_HELP_STRING([--with-libgcrypt], [use libgcrypt for low-level crypto]),
     libgcrypt=$withval, libgcrypt=no)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m4/gl-openssl.m4	Sat Nov 30 05:19:32 2013 +0000
@@ -0,0 +1,35 @@
+# gl-openssl.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 libcrypto hash routines if available: default=no])],
+    [],
+    [with_openssl=no])
+
+  if test "x$1" = xMD5; then
+    ALG_header=md5.h
+  else
+    ALG_header=sha.h
+  fi
+
+  LIB_CRYPTO=
+  AC_SUBST([LIB_CRYPTO])
+  if test "x$with_openssl" != xno; then
+    AC_CHECK_LIB([crypto], [$1],
+      [AC_CHECK_HEADERS([openssl/$ALG_header],
+        [LIB_CRYPTO='-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" = x; then
+        AC_MSG_WARN([openssl development library not found for $1])
+      fi
+    fi
+  fi
+])
--- a/m4/md5.m4	Fri Nov 29 15:35:33 2013 +0000
+++ b/m4/md5.m4	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
 [
   dnl Prerequisites of lib/md5.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_MD5 and LIB_CRYPTO
+  gl_CRYPTO_CHECK([MD5])
 ])
--- a/m4/sha1.m4	Fri Nov 29 15:35:33 2013 +0000
+++ b/m4/sha1.m4	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
 [
   dnl Prerequisites of lib/sha1.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_SHA1 and LIB_CRYPTO
+  gl_CRYPTO_CHECK([SHA1])
 ])
--- a/m4/sha256.m4	Fri Nov 29 15:35:33 2013 +0000
+++ b/m4/sha256.m4	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
 [
   dnl Prerequisites of lib/sha256.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_SHA256 and LIB_CRYPTO
+  gl_CRYPTO_CHECK([SHA256])
 ])
--- a/m4/sha512.m4	Fri Nov 29 15:35:33 2013 +0000
+++ b/m4/sha512.m4	Sat Nov 30 05:19:32 2013 +0000
@@ -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 @@
 [
   dnl Prerequisites of lib/sha512.c.
   AC_REQUIRE([gl_BIGENDIAN])
-  :
+
+  dnl Determine HAVE_OPENSSL_SHA512 and LIB_CRYPTO
+  gl_CRYPTO_CHECK([SHA512])
 ])
--- a/modules/crypto/gc-des-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-des-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-des
 check_PROGRAMS += test-gc-des
+test_gc_des_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-hmac-md5-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-hmac-md5-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-hmac-md5
 check_PROGRAMS += test-gc-hmac-md5
+test_gc_hmac_md5_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-hmac-sha1-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-hmac-sha1-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-hmac-sha1
 check_PROGRAMS += test-gc-hmac-sha1
+test_gc_hmac_sha1_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-hmac-sha256-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-hmac-sha256-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-hmac-sha256
 check_PROGRAMS += test-gc-hmac-sha256
+test_gc_hmac_sha256_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-hmac-sha512-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-hmac-sha512-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-hmac-sha512
 check_PROGRAMS += test-gc-hmac-sha512
+test_gc_hmac_sha512_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-md5-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-md5-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-md5
 check_PROGRAMS += test-gc-md5
+test_gc_md5_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-pbkdf2-sha1-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-pbkdf2-sha1-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-pbkdf2-sha1
 check_PROGRAMS += test-gc-pbkdf2-sha1
+test_gc_pbkdf2_sha1_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-sha1-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-sha1-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc-sha1
 check_PROGRAMS += test-gc-sha1
+test_gc_sha1_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/gc-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/gc-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-gc
 check_PROGRAMS += test-gc
+test_gc_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/hmac-md5-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/hmac-md5-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-hmac-md5
 check_PROGRAMS += test-hmac-md5
+test_hmac_md5_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/hmac-sha1-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/hmac-sha1-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-hmac-sha1
 check_PROGRAMS += test-hmac-sha1
+test_hmac_sha1_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/hmac-sha256-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/hmac-sha256-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-hmac-sha256
 check_PROGRAMS += test-hmac-sha256
+test_hmac_sha256_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/hmac-sha512-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/hmac-sha512-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-hmac-sha512
 check_PROGRAMS += test-hmac-sha512
+test_hmac_sha512_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/md5	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/md5	Sat Nov 30 05:19:32 2013 +0000
@@ -2,11 +2,14 @@
 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 @@
 Include:
 "md5.h"
 
+Link:
+$(LIB_CRYPTO)
+
 License:
 LGPLv2+
 
--- a/modules/crypto/md5-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/md5-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-md5
 check_PROGRAMS += test-md5
+test_md5_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/sha1	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/sha1	Sat Nov 30 05:19:32 2013 +0000
@@ -2,11 +2,14 @@
 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 @@
 Include:
 "sha1.h"
 
+Link:
+$(LIB_CRYPTO)
+
 License:
 LGPLv2+
 
--- a/modules/crypto/sha1-tests	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/sha1-tests	Sat Nov 30 05:19:32 2013 +0000
@@ -8,3 +8,4 @@
 Makefile.am:
 TESTS += test-sha1
 check_PROGRAMS += test-sha1
+test_sha1_LDADD = $(LDADD) @LIB_CRYPTO@
--- a/modules/crypto/sha256	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/sha256	Sat Nov 30 05:19:32 2013 +0000
@@ -2,11 +2,14 @@
 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 @@
 Include:
 "sha256.h"
 
+Link:
+$(LIB_CRYPTO)
+
 License:
 LGPLv2+
 
--- a/modules/crypto/sha512	Fri Nov 29 15:35:33 2013 +0000
+++ b/modules/crypto/sha512	Sat Nov 30 05:19:32 2013 +0000
@@ -2,11 +2,14 @@
 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 @@
 Include:
 "sha512.h"
 
+Link:
+$(LIB_CRYPTO)
+
 License:
 LGPLv2+