diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2013-12-08 00:05:36 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2013-12-08 00:05:36 -0800 |
commit | e9551b12f8c17876a32e1cd075c83af3e7950980 (patch) | |
tree | a1130605fdba681c9118c71f5edd4ee2b9ef4c51 /lib | |
parent | 02033d491fa708e28bb3568ff85dab4d0ceb076b (diff) | |
download | emacs-e9551b12f8c17876a32e1cd075c83af3e7950980.tar.gz |
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
<http://lists.gnu.org/archive/html/bug-gnulib/2013-12/msg00000.html>.
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gl_openssl.h | 116 | ||||
-rw-r--r-- | lib/gnulib.mk | 17 | ||||
-rw-r--r-- | lib/md5.c | 7 | ||||
-rw-r--r-- | lib/md5.h | 20 | ||||
-rw-r--r-- | lib/sha1.c | 7 | ||||
-rw-r--r-- | lib/sha1.h | 21 | ||||
-rw-r--r-- | lib/sha256.c | 7 | ||||
-rw-r--r-- | lib/sha256.h | 30 | ||||
-rw-r--r-- | lib/sha512.c | 7 | ||||
-rw-r--r-- | lib/sha512.h | 31 |
10 files changed, 229 insertions, 34 deletions
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 <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/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 <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 634a7470f44..b09a68b148d 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 778389affc5..b1a24f9968d 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 ddd386f9144..0ec953e8357 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 4b2cee37fb5..9d6912cdc79 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 7e6252285bb..6ee326b0466 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 79f11257474..8429bb9b03a 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 2e78a5f9404..1de93da2f8a 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 |