From e9551b12f8c17876a32e1cd075c83af3e7950980 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 8 Dec 2013 00:05:36 -0800 Subject: [PATCH] Use libcrypto's checksum implementations if available, for speed. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit On commonly used platform libcrypto uses architecture-specific assembly code, which is significantly faster than the C code we were using. See Pádraig Brady's note in . Merge from gnulib, incorporating: 2013-12-07 md5, sha1, sha256, sha512: add gl_SET_CRYPTO_CHECK_DEFAULT 2013-12-07 md5, sha1, sha256, sha512: add 'auto', and set-default method 2013-12-04 include_next: minimize code duplication 2013-12-03 md5, sha1, sha256, sha512: support mandating use of openssl 2013-12-02 md5, sha1, sha256, sha512: use openssl routines if available * configure.ac (--without-all): Set with_openssl_default too. Use gl_SET_CRYPTO_CHECK_DEFAULT to default to 'auto'. (HAVE_LIB_CRYPTO): New var. Say whether Emacs is configured to use a crypto library. * lib/gl_openssl.h, m4/absolute-header.m4, m4/gl-openssl.m4: New files, copied from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * 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/include_next.m4, m4/md5.m4, m4/sha1.m4, m4/sha256.m4, m4/sha512.m4: Update from gnulib. * src/Makefile.in (LIB_CRYPTO): New macro. (LIBES): Use it. --- ChangeLog | 25 +++++++++ configure.ac | 13 ++++- lib/gl_openssl.h | 116 ++++++++++++++++++++++++++++++++++++++++++ lib/gnulib.mk | 17 +++++-- 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/absolute-header.m4 | 102 +++++++++++++++++++++++++++++++++++++ m4/gl-openssl.m4 | 48 +++++++++++++++++ m4/gnulib-comp.m4 | 4 ++ m4/include_next.m4 | 53 ++----------------- m4/md5.m4 | 6 ++- m4/sha1.m4 | 6 ++- m4/sha256.m4 | 6 ++- m4/sha512.m4 | 6 ++- src/ChangeLog | 4 ++ src/Makefile.in | 2 + 22 files changed, 444 insertions(+), 94 deletions(-) create mode 100644 lib/gl_openssl.h create mode 100644 m4/absolute-header.m4 create mode 100644 m4/gl-openssl.m4 diff --git a/ChangeLog b/ChangeLog index 6183719e98c..724218c1d35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2013-12-08 Paul Eggert + + Use libcrypto's checksum implementations if available, for speed. + On commonly used platform libcrypto uses architecture-specific + assembly code, which is significantly faster than the C code we + were using. See Pádraig Brady's note in + . + Merge from gnulib, incorporating: + 2013-12-07 md5, sha1, sha256, sha512: add gl_SET_CRYPTO_CHECK_DEFAULT + 2013-12-07 md5, sha1, sha256, sha512: add 'auto', and set-default method + 2013-12-04 include_next: minimize code duplication + 2013-12-03 md5, sha1, sha256, sha512: support mandating use of openssl + 2013-12-02 md5, sha1, sha256, sha512: use openssl routines if available + * configure.ac (--without-all): Set with_openssl_default too. + Use gl_SET_CRYPTO_CHECK_DEFAULT to default to 'auto'. + (HAVE_LIB_CRYPTO): New var. + Say whether Emacs is configured to use a crypto library. + * lib/gl_openssl.h, m4/absolute-header.m4, m4/gl-openssl.m4: + New files, copied from gnulib. + * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. + * 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/include_next.m4, m4/md5.m4, m4/sha1.m4, m4/sha256.m4, m4/sha512.m4: + Update from gnulib. + 2013-12-01 Dmitry Gutov * .dir-locals.el (log-edit-move): Add the "Author: " header. diff --git a/configure.ac b/configure.ac index 46ddb43635c..264c339ed6e 100644 --- a/configure.ac +++ b/configure.ac @@ -94,8 +94,9 @@ AC_ARG_WITH(all, [AS_HELP_STRING([--without-all], [omit almost all features and build small executable with minimal dependencies])], - with_features=$withval, - with_features=yes) + [with_features=$withval + with_openssl_default=$withval], + [with_features=yes]) dnl OPTION_DEFAULT_OFF(NAME, HELP-STRING) dnl Create a new --with option that defaults to being disabled. @@ -4691,6 +4692,7 @@ CFLAGS=$pre_PKG_CONFIG_CFLAGS LIBS="$LIB_PTHREAD $pre_PKG_CONFIG_LIBS" gl_ASSERT_NO_GNULIB_POSIXCHECK gl_ASSERT_NO_GNULIB_TESTS +gl_SET_CRYPTO_CHECK_DEFAULT([auto]) gl_INIT CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS @@ -4842,6 +4844,12 @@ else acl_summary=no fi +if test -n "$LIB_CRYPTO"; then + HAVE_LIB_CRYPTO=yes +else + HAVE_LIB_CRYPTO=no +fi + echo " Configured for \`${canonical}'. @@ -4881,6 +4889,7 @@ echo " Does Emacs use -lgconf? ${HAVE_GCONF}" echo " Does Emacs use GSettings? ${HAVE_GSETTINGS}" echo " Does Emacs use a file notification library? ${NOTIFY_SUMMARY}" echo " Does Emacs use access control lists? ${acl_summary}" +echo " Does Emacs use a crypto library? ${HAVE_LIB_CRYPTO} $LIB_CRYPTO" echo " Does Emacs use -lselinux? ${HAVE_LIBSELINUX}" echo " Does Emacs use -lgnutls? ${HAVE_GNUTLS}" echo " Does Emacs use -lxml2? ${HAVE_LIBXML2}" diff --git a/lib/gl_openssl.h b/lib/gl_openssl.h new file mode 100644 index 00000000000..1fb61066b11 --- /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 . */ + +/* 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/gnulib.mk b/lib/gnulib.mk index 44cdc0cdaac..9617452a796 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -33,6 +33,15 @@ libgnu_a_LIBADD = $(gl_LIBOBJS) libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) EXTRA_libgnu_a_SOURCES = +## begin gnulib module absolute-header + +# Use this preprocessor expression to decide whether #include_next works. +# Do not rely on a 'configure'-time test for this, since the expression +# might appear in an installed header, which is used by some other compiler. +HAVE_INCLUDE_NEXT = (__GNUC__ || 60000000 <= __DECC_VER) + +## end gnulib module absolute-header + ## begin gnulib module alloca-opt BUILT_SOURCES += $(ALLOCA_H) @@ -152,7 +161,7 @@ EXTRA_DIST += count-trailing-zeros.h libgnu_a_SOURCES += md5.c -EXTRA_DIST += md5.h +EXTRA_DIST += gl_openssl.h md5.h ## end gnulib module crypto/md5 @@ -160,7 +169,7 @@ EXTRA_DIST += md5.h libgnu_a_SOURCES += sha1.c -EXTRA_DIST += sha1.h +EXTRA_DIST += gl_openssl.h sha1.h ## end gnulib module crypto/sha1 @@ -168,7 +177,7 @@ EXTRA_DIST += sha1.h libgnu_a_SOURCES += sha256.c -EXTRA_DIST += sha256.h +EXTRA_DIST += gl_openssl.h sha256.h ## end gnulib module crypto/sha256 @@ -176,7 +185,7 @@ EXTRA_DIST += sha256.h libgnu_a_SOURCES += sha512.c -EXTRA_DIST += sha512.h +EXTRA_DIST += gl_openssl.h sha512.h ## end gnulib module crypto/sha512 diff --git a/lib/md5.c b/lib/md5.c index f41b5beb7ce..ea2c1d5f3f8 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -21,6 +21,9 @@ #include +#if HAVE_OPENSSL_MD5 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif #include "md5.h" #include @@ -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 634a7470f44..b09a68b148d 100644 --- a/lib/md5.h +++ b/lib/md5.h @@ -23,6 +23,10 @@ #include #include +# if HAVE_OPENSSL_MD5 +# include +# 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 778389affc5..b1a24f9968d 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -23,6 +23,9 @@ #include +#if HAVE_OPENSSL_SHA1 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif #include "sha1.h" #include @@ -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 ddd386f9144..0ec953e8357 100644 --- a/lib/sha1.h +++ b/lib/sha1.h @@ -22,12 +22,20 @@ # include # include +# if HAVE_OPENSSL_SHA1 +# include +# 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 4b2cee37fb5..9d6912cdc79 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -22,6 +22,9 @@ #include +#if HAVE_OPENSSL_SHA256 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif #include "sha256.h" #include @@ -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 7e6252285bb..6ee326b0466 100644 --- a/lib/sha256.h +++ b/lib/sha256.h @@ -21,10 +21,23 @@ # include # include +# if HAVE_OPENSSL_SHA256 +# include +# 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 79f11257474..8429bb9b03a 100644 --- a/lib/sha512.c +++ b/lib/sha512.c @@ -22,6 +22,9 @@ #include +#if HAVE_OPENSSL_SHA512 +# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE +#endif #include "sha512.h" #include @@ -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 2e78a5f9404..1de93da2f8a 100644 --- a/lib/sha512.h +++ b/lib/sha512.h @@ -19,13 +19,25 @@ # define SHA512_H 1 # include - # include "u64.h" +# if HAVE_OPENSSL_SHA512 +# include +# 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/absolute-header.m4 b/m4/absolute-header.m4 new file mode 100644 index 00000000000..89ff5beb65f --- /dev/null +++ b/m4/absolute-header.m4 @@ -0,0 +1,102 @@ +# absolute-header.m4 serial 16 +dnl Copyright (C) 2006-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. + +dnl From Derek Price. + +# gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...) +# --------------------------------------- +# Find the absolute name of a header file, testing first if the header exists. +# If the header were sys/inttypes.h, this macro would define +# ABSOLUTE_SYS_INTTYPES_H to the '""' quoted absolute name of sys/inttypes.h +# in config.h +# (e.g. '#define ABSOLUTE_SYS_INTTYPES_H "///usr/include/sys/inttypes.h"'). +# The three "///" are to pacify Sun C 5.8, which otherwise would say +# "warning: #include of /usr/include/... may be non-portable". +# Use '""', not '<>', so that the /// cannot be confused with a C99 comment. +# Note: This macro assumes that the header file is not empty after +# preprocessing, i.e. it does not only define preprocessor macros but also +# provides some type/enum definitions or function/variable declarations. +AC_DEFUN([gl_ABSOLUTE_HEADER], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_PREPROC_REQUIRE()dnl +dnl FIXME: gl_absolute_header and ac_header_exists must be used unquoted +dnl until we can assume autoconf 2.64 or newer. +m4_foreach_w([gl_HEADER_NAME], [$1], + [AS_VAR_PUSHDEF([gl_absolute_header], + [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl + AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>], + m4_defn([gl_absolute_header]), + [AS_VAR_PUSHDEF([ac_header_exists], + [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl + AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl + if test AS_VAR_GET(ac_header_exists) = yes; then + gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME])) + fi + AS_VAR_POPDEF([ac_header_exists])dnl + ])dnl + AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])), + ["AS_VAR_GET(gl_absolute_header)"], + [Define this to an absolute name of <]m4_defn([gl_HEADER_NAME])[>.]) + AS_VAR_POPDEF([gl_absolute_header])dnl +])dnl +])# gl_ABSOLUTE_HEADER + +# gl_ABSOLUTE_HEADER_ONE(HEADER) +# ------------------------------ +# Like gl_ABSOLUTE_HEADER, except that: +# - it assumes that the header exists, +# - it uses the current CPPFLAGS, +# - it does not cache the result, +# - it is silent. +AC_DEFUN([gl_ABSOLUTE_HEADER_ONE], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote([$1])[[>]])]) + dnl AIX "xlc -E" and "cc -E" omit #line directives for header files + dnl that contain only a #include of other header files and no + dnl non-comment tokens of their own. This leads to a failure to + dnl detect the absolute name of , , + dnl and others. The workaround is to force preservation of comments + dnl through option -C. This ensures all necessary #line directives + dnl are present. GCC supports option -C as well. + case "$host_os" in + aix*) gl_absname_cpp="$ac_cpp -C" ;; + *) gl_absname_cpp="$ac_cpp" ;; + esac +changequote(,) + case "$host_os" in + mingw*) + dnl For the sake of native Windows compilers (excluding gcc), + dnl treat backslash as a directory separator, like /. + dnl Actually, these compilers use a double-backslash as + dnl directory separator, inside the + dnl # line "filename" + dnl directives. + gl_dirsep_regex='[/\\]' + ;; + *) + gl_dirsep_regex='\/' + ;; + esac + dnl A sed expression that turns a string into a basic regular + dnl expression, for use within "/.../". + gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' + gl_header_literal_regex=`echo '$1' \ + | sed -e "$gl_make_literal_regex_sed"` + gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ + s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ + s|^/[^/]|//&| + p + q + }' +changequote([,]) + dnl eval is necessary to expand gl_absname_cpp. + dnl Ultrix and Pyramid sh refuse to redirect output of eval, + dnl so use subshell. + AS_VAR_SET([gl_cv_absolute_]AS_TR_SH([[$1]]), +[`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | + sed -n "$gl_absolute_header_sed"`]) +]) diff --git a/m4/gl-openssl.m4 b/m4/gl-openssl.m4 new file mode 100644 index 00000000000..c8f9dd95e68 --- /dev/null +++ b/m4/gl-openssl.m4 @@ -0,0 +1,48 @@ +# gl-openssl.m4 serial 3 +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_SET_CRYPTO_CHECK_DEFAULT], +[ + m4_define([gl_CRYPTO_CHECK_DEFAULT], [$1]) +]) +gl_SET_CRYPTO_CHECK_DEFAULT([no]) + +AC_DEFUN([gl_CRYPTO_CHECK], +[ + m4_divert_once([DEFAULTS], [with_openssl_default='gl_CRYPTO_CHECK_DEFAULT']) + + AC_ARG_WITH([openssl], + [AS_HELP_STRING([--with-openssl], + [use libcrypto hash routines. Valid ARGs are: + 'yes', 'no', 'auto' => use if available, + 'optional' => use if available and warn if not available; + default is ']gl_CRYPTO_CHECK_DEFAULT['])], + [], + [with_openssl=$with_openssl_default]) + + 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$LIB_CRYPTO" = x; then + if test "x$with_openssl" = xyes; then + AC_MSG_ERROR([openssl development library not found for $1]) + elif test "x$with_openssl" = xoptional; then + AC_MSG_WARN([openssl development library not found for $1]) + fi + fi + fi +]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index c707e34993d..3a04c84ac90 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -38,6 +38,7 @@ AC_DEFUN([gl_EARLY], m4_pattern_allow([^gl_LIBOBJS$])dnl a variable m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable AC_REQUIRE([gl_PROG_AR_RANLIB]) + # Code from module absolute-header: # Code from module alloca-opt: # Code from module allocator: # Code from module at-internal: @@ -847,6 +848,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/gettext.h lib/gettime.c lib/gettimeofday.c + lib/gl_openssl.h lib/group-member.c lib/intprops.h lib/inttypes.in.h @@ -921,6 +923,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/verify.h lib/xalloc-oversized.h m4/00gnulib.m4 + m4/absolute-header.m4 m4/acl.m4 m4/alloca.m4 m4/byteswap.m4 @@ -953,6 +956,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/getopt.m4 m4/gettime.m4 m4/gettimeofday.m4 + m4/gl-openssl.m4 m4/gnulib-common.m4 m4/group-member.m4 m4/include_next.m4 diff --git a/m4/include_next.m4 b/m4/include_next.m4 index 108d945677f..f09dbe66395 100644 --- a/m4/include_next.m4 +++ b/m4/include_next.m4 @@ -192,56 +192,9 @@ dnl until we can assume autoconf 2.64 or newer. if test AS_VAR_GET(gl_header_exists) = yes; then AS_VAR_POPDEF([gl_header_exists]) ]) - AC_LANG_CONFTEST( - [AC_LANG_SOURCE( - [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] - )]) - dnl AIX "xlc -E" and "cc -E" omit #line directives for header - dnl files that contain only a #include of other header files and - dnl no non-comment tokens of their own. This leads to a failure - dnl to detect the absolute name of , , - dnl and others. The workaround is to force preservation - dnl of comments through option -C. This ensures all necessary - dnl #line directives are present. GCC supports option -C as well. - case "$host_os" in - aix*) gl_absname_cpp="$ac_cpp -C" ;; - *) gl_absname_cpp="$ac_cpp" ;; - esac -changequote(,) - case "$host_os" in - mingw*) - dnl For the sake of native Windows compilers (excluding gcc), - dnl treat backslash as a directory separator, like /. - dnl Actually, these compilers use a double-backslash as - dnl directory separator, inside the - dnl # line "filename" - dnl directives. - gl_dirsep_regex='[/\\]' - ;; - *) - gl_dirsep_regex='\/' - ;; - esac - dnl A sed expression that turns a string into a basic regular - dnl expression, for use within "/.../". - gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' -changequote([,]) - gl_header_literal_regex=`echo ']m4_defn([gl_HEADER_NAME])[' \ - | sed -e "$gl_make_literal_regex_sed"` - gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ - s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ -changequote(,)dnl - s|^/[^/]|//&| -changequote([,])dnl - p - q - }' - dnl eval is necessary to expand gl_absname_cpp. - dnl Ultrix and Pyramid sh refuse to redirect output of eval, - dnl so use subshell. - AS_VAR_SET(gl_next_header, - ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | - sed -n "$gl_absolute_header_sed"`'"']) + gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME) + AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME)) + AS_VAR_SET(gl_next_header, ['"'$gl_header'"']) m4_if([$2], [check], [else AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) diff --git a/m4/md5.m4 b/m4/md5.m4 index 0ad6f504b53..541a26b5298 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 + gl_CRYPTO_CHECK([MD5]) ]) diff --git a/m4/sha1.m4 b/m4/sha1.m4 index 21c775e364e..57d5256652a 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 + gl_CRYPTO_CHECK([SHA1]) ]) diff --git a/m4/sha256.m4 b/m4/sha256.m4 index cbbd17a6444..3a194674697 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 + gl_CRYPTO_CHECK([SHA256]) ]) diff --git a/m4/sha512.m4 b/m4/sha512.m4 index f4a6bf13baa..d929195e9a2 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 + gl_CRYPTO_CHECK([SHA512]) ]) diff --git a/src/ChangeLog b/src/ChangeLog index 5daf1dc5a7c..1eba6bb71c4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,9 @@ 2013-12-08 Paul Eggert + Use libcrypto's checksum implementations if available, for speed. + * Makefile.in (LIB_CRYPTO): New macro. + (LIBES): Use it. + * frame.h (SET_FRAME_VISIBLE): Now an inline function. The macro didn't conform to C99 due to type mismatch, which caused compilation failure with Sun C 5.12, diff --git a/src/Makefile.in b/src/Makefile.in index 7d91928acfe..cef1ba5ed2e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -139,6 +139,7 @@ M17N_FLT_LIBS = @M17N_FLT_LIBS@ LIB_ACL=@LIB_ACL@ LIB_CLOCK_GETTIME=@LIB_CLOCK_GETTIME@ +LIB_CRYPTO=@LIB_CRYPTO@ LIB_EACCESS=@LIB_EACCESS@ LIB_FDATASYNC=@LIB_FDATASYNC@ LIB_TIMER_TIME=@LIB_TIMER_TIME@ @@ -403,6 +404,7 @@ ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj) LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(LIBX_OTHER) $(LIBSOUND) \ $(RSVG_LIBS) $(IMAGEMAGICK_LIBS) $(LIB_ACL) $(LIB_CLOCK_GETTIME) \ + $(LIB_CRYPTO) \ $(LIB_EACCESS) $(LIB_FDATASYNC) $(LIB_TIMER_TIME) $(DBUS_LIBS) \ $(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) \ $(LIBXML2_LIBS) $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ -- 2.39.2