* Optional switch "--with-openssl=<PATH>" to use OpenSSL's
implementations of MD5, SHA-1 and SHA-256. The main benefit is that we get assembler-optimised implementations of MD5 and SHA-1 (though not SHA-256 (at least on x86), unfortunately). OpenSSL's SHA-1 implementation on Intel is twice as fast as ours.
This commit is contained in:
parent
e8475bbd5b
commit
d6f586d0ea
7 changed files with 59 additions and 40 deletions
11
configure.ac
11
configure.ac
|
@ -143,6 +143,17 @@ AC_SUBST(aterm_lib)
|
||||||
AC_SUBST(aterm_include)
|
AC_SUBST(aterm_include)
|
||||||
AC_SUBST(aterm_bin)
|
AC_SUBST(aterm_bin)
|
||||||
|
|
||||||
|
AC_ARG_WITH(openssl, AC_HELP_STRING([--with-openssl=PATH],
|
||||||
|
[prefix of the OpenSSL library]),
|
||||||
|
openssl=$withval, openssl=)
|
||||||
|
AM_CONDITIONAL(HAVE_OPENSSL, test -n "$openssl")
|
||||||
|
if test -n "$openssl"; then
|
||||||
|
LDFLAGS="-L$openssl/lib -lcrypto $LDFLAGS"
|
||||||
|
CFLAGS="-I$openssl/include $CFLAGS"
|
||||||
|
CXXFLAGS="-I$openssl/include $CXXFLAGS"
|
||||||
|
AC_DEFINE(HAVE_OPENSSL, 1, [whether to use OpenSSL])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_ARG_WITH(bzip2, AC_HELP_STRING([--with-bzip2=PATH],
|
AC_ARG_WITH(bzip2, AC_HELP_STRING([--with-bzip2=PATH],
|
||||||
[prefix of bzip2]),
|
[prefix of bzip2]),
|
||||||
bzip2=$withval, bzip2=)
|
bzip2=$withval, bzip2=)
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
lib_LTLIBRARIES = libutil.la
|
lib_LTLIBRARIES = libutil.la
|
||||||
|
|
||||||
libutil_la_SOURCES = util.cc util.hh hash.cc hash.hh \
|
libutil_la_SOURCES = util.cc util.hh hash.cc hash.hh \
|
||||||
archive.cc archive.hh aterm.cc aterm.hh \
|
archive.cc archive.hh aterm.cc aterm.hh
|
||||||
|
|
||||||
|
if !HAVE_OPENSSL
|
||||||
|
libutil_la_SOURCES += \
|
||||||
md5.c md5.h sha1.c sha1.h sha256.c sha256.h md32_common.h
|
md5.c md5.h sha1.c sha1.h sha256.c sha256.h md32_common.h
|
||||||
|
endif
|
||||||
|
|
||||||
AM_CXXFLAGS = -Wall -I.. ${aterm_include}
|
AM_CXXFLAGS = -Wall -I.. ${aterm_include}
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#else
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
#include "sha256.h"
|
#include "sha256.h"
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "hash.hh"
|
#include "hash.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
|
@ -199,16 +206,16 @@ bool isHash(const string & s)
|
||||||
|
|
||||||
union Ctx
|
union Ctx
|
||||||
{
|
{
|
||||||
md5_ctx md5;
|
MD5_CTX md5;
|
||||||
sha_ctx sha1;
|
SHA_CTX sha1;
|
||||||
SHA256_CTX sha256;
|
SHA256_CTX sha256;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void start(HashType ht, Ctx & ctx)
|
static void start(HashType ht, Ctx & ctx)
|
||||||
{
|
{
|
||||||
if (ht == htMD5) md5_init_ctx(&ctx.md5);
|
if (ht == htMD5) MD5_Init(&ctx.md5);
|
||||||
else if (ht == htSHA1) sha_init(&ctx.sha1);
|
else if (ht == htSHA1) SHA1_Init(&ctx.sha1);
|
||||||
else if (ht == htSHA256) SHA256_Init(&ctx.sha256);
|
else if (ht == htSHA256) SHA256_Init(&ctx.sha256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,19 +223,16 @@ static void start(HashType ht, Ctx & ctx)
|
||||||
static void update(HashType ht, Ctx & ctx,
|
static void update(HashType ht, Ctx & ctx,
|
||||||
const unsigned char * bytes, unsigned int len)
|
const unsigned char * bytes, unsigned int len)
|
||||||
{
|
{
|
||||||
if (ht == htMD5) md5_process_bytes(bytes, len, &ctx.md5);
|
if (ht == htMD5) MD5_Update(&ctx.md5, bytes, len);
|
||||||
else if (ht == htSHA1) sha_update(&ctx.sha1, bytes, len);
|
else if (ht == htSHA1) SHA1_Update(&ctx.sha1, bytes, len);
|
||||||
else if (ht == htSHA256) SHA256_Update(&ctx.sha256, bytes, len);
|
else if (ht == htSHA256) SHA256_Update(&ctx.sha256, bytes, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void finish(HashType ht, Ctx & ctx, unsigned char * hash)
|
static void finish(HashType ht, Ctx & ctx, unsigned char * hash)
|
||||||
{
|
{
|
||||||
if (ht == htMD5) md5_finish_ctx(&ctx.md5, hash);
|
if (ht == htMD5) MD5_Final(hash, &ctx.md5);
|
||||||
else if (ht == htSHA1) {
|
else if (ht == htSHA1) SHA1_Final(hash, &ctx.sha1);
|
||||||
sha_final(&ctx.sha1);
|
|
||||||
sha_digest(&ctx.sha1, hash);
|
|
||||||
}
|
|
||||||
else if (ht == htSHA256) SHA256_Final(hash, &ctx.sha256);
|
else if (ht == htSHA256) SHA256_Final(hash, &ctx.sha256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,8 @@ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
|
||||||
/* Initialize structure containing state of computation.
|
/* Initialize structure containing state of computation.
|
||||||
(RFC 1321, 3.3: Step 3) */
|
(RFC 1321, 3.3: Step 3) */
|
||||||
void
|
void
|
||||||
md5_init_ctx (ctx)
|
MD5_Init (ctx)
|
||||||
struct md5_ctx *ctx;
|
struct MD5_CTX *ctx;
|
||||||
{
|
{
|
||||||
ctx->A = 0x67452301;
|
ctx->A = 0x67452301;
|
||||||
ctx->B = 0xefcdab89;
|
ctx->B = 0xefcdab89;
|
||||||
|
@ -75,7 +75,7 @@ md5_init_ctx (ctx)
|
||||||
aligned for a 32 bits value. */
|
aligned for a 32 bits value. */
|
||||||
void *
|
void *
|
||||||
md5_read_ctx (ctx, resbuf)
|
md5_read_ctx (ctx, resbuf)
|
||||||
const struct md5_ctx *ctx;
|
const struct MD5_CTX *ctx;
|
||||||
void *resbuf;
|
void *resbuf;
|
||||||
{
|
{
|
||||||
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
|
((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
|
||||||
|
@ -92,9 +92,9 @@ md5_read_ctx (ctx, resbuf)
|
||||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
aligned for a 32 bits value. */
|
aligned for a 32 bits value. */
|
||||||
void *
|
void *
|
||||||
md5_finish_ctx (ctx, resbuf)
|
MD5_Final (resbuf, ctx)
|
||||||
struct md5_ctx *ctx;
|
|
||||||
void *resbuf;
|
void *resbuf;
|
||||||
|
struct MD5_CTX *ctx;
|
||||||
{
|
{
|
||||||
/* Take yet unprocessed bytes into account. */
|
/* Take yet unprocessed bytes into account. */
|
||||||
md5_uint32 bytes = ctx->buflen;
|
md5_uint32 bytes = ctx->buflen;
|
||||||
|
@ -120,10 +120,10 @@ md5_finish_ctx (ctx, resbuf)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
md5_process_bytes (buffer, len, ctx)
|
MD5_Update (ctx, buffer, len)
|
||||||
|
struct MD5_CTX *ctx;
|
||||||
const void *buffer;
|
const void *buffer;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct md5_ctx *ctx;
|
|
||||||
{
|
{
|
||||||
/* When we already have some bits in our internal buffer concatenate
|
/* When we already have some bits in our internal buffer concatenate
|
||||||
both inputs first. */
|
both inputs first. */
|
||||||
|
@ -210,7 +210,7 @@ void
|
||||||
md5_process_block (buffer, len, ctx)
|
md5_process_block (buffer, len, ctx)
|
||||||
const void *buffer;
|
const void *buffer;
|
||||||
size_t len;
|
size_t len;
|
||||||
struct md5_ctx *ctx;
|
struct MD5_CTX *ctx;
|
||||||
{
|
{
|
||||||
md5_uint32 correct_words[16];
|
md5_uint32 correct_words[16];
|
||||||
const md5_uint32 *words = buffer;
|
const md5_uint32 *words = buffer;
|
||||||
|
|
|
@ -26,7 +26,7 @@ typedef uint32_t md5_uint32;
|
||||||
typedef uintptr_t md5_uintptr;
|
typedef uintptr_t md5_uintptr;
|
||||||
|
|
||||||
/* Structure to save state of computation between the single steps. */
|
/* Structure to save state of computation between the single steps. */
|
||||||
struct md5_ctx
|
struct MD5_CTX
|
||||||
{
|
{
|
||||||
md5_uint32 A;
|
md5_uint32 A;
|
||||||
md5_uint32 B;
|
md5_uint32 B;
|
||||||
|
@ -45,21 +45,20 @@ struct md5_ctx
|
||||||
|
|
||||||
/* Initialize structure containing state of computation.
|
/* Initialize structure containing state of computation.
|
||||||
(RFC 1321, 3.3: Step 3) */
|
(RFC 1321, 3.3: Step 3) */
|
||||||
extern void md5_init_ctx __P ((struct md5_ctx *ctx));
|
extern void MD5_Init __P ((struct MD5_CTX *ctx));
|
||||||
|
|
||||||
/* Starting with the result of former calls of this function (or the
|
/* Starting with the result of former calls of this function (or the
|
||||||
initialization function update the context for the next LEN bytes
|
initialization function update the context for the next LEN bytes
|
||||||
starting at BUFFER.
|
starting at BUFFER.
|
||||||
It is necessary that LEN is a multiple of 64!!! */
|
It is necessary that LEN is a multiple of 64!!! */
|
||||||
extern void md5_process_block __P ((const void *buffer, size_t len,
|
extern void md5_process_block __P ((const void *buffer, size_t len,
|
||||||
struct md5_ctx *ctx));
|
struct MD5_CTX *ctx));
|
||||||
|
|
||||||
/* Starting with the result of former calls of this function (or the
|
/* Starting with the result of former calls of this function (or the
|
||||||
initialization function update the context for the next LEN bytes
|
initialization function update the context for the next LEN bytes
|
||||||
starting at BUFFER.
|
starting at BUFFER.
|
||||||
It is NOT required that LEN is a multiple of 64. */
|
It is NOT required that LEN is a multiple of 64. */
|
||||||
extern void md5_process_bytes __P ((const void *buffer, size_t len,
|
extern void MD5_Update __P ((struct MD5_CTX *ctx, const void *buffer, size_t len));
|
||||||
struct md5_ctx *ctx));
|
|
||||||
|
|
||||||
/* Process the remaining bytes in the buffer and put result from CTX
|
/* Process the remaining bytes in the buffer and put result from CTX
|
||||||
in first 16 bytes following RESBUF. The result is always in little
|
in first 16 bytes following RESBUF. The result is always in little
|
||||||
|
@ -68,7 +67,7 @@ extern void md5_process_bytes __P ((const void *buffer, size_t len,
|
||||||
|
|
||||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
aligned for a 32 bits value. */
|
aligned for a 32 bits value. */
|
||||||
extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
|
extern void *MD5_Final __P ((void *resbuf, struct MD5_CTX *ctx));
|
||||||
|
|
||||||
|
|
||||||
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
/* Put result from CTX in first 16 bytes following RESBUF. The result is
|
||||||
|
@ -77,7 +76,7 @@ extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf));
|
||||||
|
|
||||||
IMPORTANT: On some systems it is required that RESBUF is correctly
|
IMPORTANT: On some systems it is required that RESBUF is correctly
|
||||||
aligned for a 32 bits value. */
|
aligned for a 32 bits value. */
|
||||||
extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
|
extern void *md5_read_ctx __P ((const struct MD5_CTX *ctx, void *resbuf));
|
||||||
|
|
||||||
|
|
||||||
#endif /* md5.h */
|
#endif /* md5.h */
|
||||||
|
|
|
@ -37,7 +37,7 @@ effort (for example the reengineering of a great many Capstone chips).
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void sha_copy(struct sha_ctx *dest, struct sha_ctx *src)
|
void sha_copy(struct SHA_CTX *dest, struct SHA_CTX *src)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ void sha_copy(struct sha_ctx *dest, struct sha_ctx *src)
|
||||||
|
|
||||||
/* Initialize the SHA values */
|
/* Initialize the SHA values */
|
||||||
|
|
||||||
void sha_init(struct sha_ctx *ctx)
|
void SHA1_Init(struct SHA_CTX *ctx)
|
||||||
{
|
{
|
||||||
/* Set the h-vars to their initial values */
|
/* Set the h-vars to their initial values */
|
||||||
ctx->digest[ 0 ] = h0init;
|
ctx->digest[ 0 ] = h0init;
|
||||||
|
@ -141,7 +141,7 @@ void sha_init(struct sha_ctx *ctx)
|
||||||
|
|
||||||
Note that this function destroys the data area */
|
Note that this function destroys the data area */
|
||||||
|
|
||||||
static void sha_transform(struct sha_ctx *ctx, uint32_t *data )
|
static void sha_transform(struct SHA_CTX *ctx, uint32_t *data )
|
||||||
{
|
{
|
||||||
uint32_t A, B, C, D, E; /* Local vars */
|
uint32_t A, B, C, D, E; /* Local vars */
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ uint32_t STRING2INT(unsigned char *s)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void sha_block(struct sha_ctx *ctx, const unsigned char *block)
|
static void sha_block(struct SHA_CTX *ctx, const unsigned char *block)
|
||||||
{
|
{
|
||||||
uint32_t data[SHA_DATALEN];
|
uint32_t data[SHA_DATALEN];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -283,7 +283,7 @@ static void sha_block(struct sha_ctx *ctx, const unsigned char *block)
|
||||||
sha_transform(ctx, data);
|
sha_transform(ctx, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sha_update(struct sha_ctx *ctx, const unsigned char *buffer, uint32_t len)
|
void SHA1_Update(struct SHA_CTX *ctx, const unsigned char *buffer, uint32_t len)
|
||||||
{
|
{
|
||||||
if (ctx->index)
|
if (ctx->index)
|
||||||
{ /* Try to fill partial block */
|
{ /* Try to fill partial block */
|
||||||
|
@ -316,7 +316,7 @@ void sha_update(struct sha_ctx *ctx, const unsigned char *buffer, uint32_t len)
|
||||||
/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
|
/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
|
||||||
1 0* (64-bit count of bits processed, MSB-first) */
|
1 0* (64-bit count of bits processed, MSB-first) */
|
||||||
|
|
||||||
void sha_final(struct sha_ctx *ctx)
|
void SHA1_Final(unsigned char *s, struct SHA_CTX *ctx)
|
||||||
{
|
{
|
||||||
uint32_t data[SHA_DATALEN];
|
uint32_t data[SHA_DATALEN];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -352,9 +352,10 @@ void sha_final(struct sha_ctx *ctx)
|
||||||
data[SHA_DATALEN-2] = (ctx->count_h << 9) | (ctx->count_l >> 23);
|
data[SHA_DATALEN-2] = (ctx->count_h << 9) | (ctx->count_l >> 23);
|
||||||
data[SHA_DATALEN-1] = (ctx->count_l << 9) | (ctx->index << 3);
|
data[SHA_DATALEN-1] = (ctx->count_l << 9) | (ctx->index << 3);
|
||||||
sha_transform(ctx, data);
|
sha_transform(ctx, data);
|
||||||
|
sha_digest(ctx, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sha_digest(struct sha_ctx *ctx, unsigned char *s)
|
void sha_digest(struct SHA_CTX *ctx, unsigned char *s)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
|
|
@ -11,18 +11,18 @@
|
||||||
#define SHA_DIGESTLEN 5
|
#define SHA_DIGESTLEN 5
|
||||||
/* The structure for storing SHA info */
|
/* The structure for storing SHA info */
|
||||||
|
|
||||||
struct sha_ctx {
|
struct SHA_CTX {
|
||||||
uint32_t digest[SHA_DIGESTLEN]; /* Message digest */
|
uint32_t digest[SHA_DIGESTLEN]; /* Message digest */
|
||||||
uint32_t count_l, count_h; /* 64-bit block count */
|
uint32_t count_l, count_h; /* 64-bit block count */
|
||||||
uint8_t block[SHA_DATASIZE]; /* SHA data buffer */
|
uint8_t block[SHA_DATASIZE]; /* SHA data buffer */
|
||||||
unsigned int index; /* index into buffer */
|
unsigned int index; /* index into buffer */
|
||||||
};
|
};
|
||||||
|
|
||||||
void sha_init(struct sha_ctx *ctx);
|
void SHA1_Init(struct SHA_CTX *ctx);
|
||||||
void sha_update(struct sha_ctx *ctx, const unsigned char *buffer, uint32_t len);
|
void SHA1_Update(struct SHA_CTX *ctx, const unsigned char *buffer, uint32_t len);
|
||||||
void sha_final(struct sha_ctx *ctx);
|
void SHA1_Final(unsigned char *s, struct SHA_CTX *ctx);
|
||||||
void sha_digest(struct sha_ctx *ctx, unsigned char *s);
|
void sha_digest(struct SHA_CTX *ctx, unsigned char *s);
|
||||||
void sha_copy(struct sha_ctx *dest, struct sha_ctx *src);
|
void sha_copy(struct SHA_CTX *dest, struct SHA_CTX *src);
|
||||||
|
|
||||||
|
|
||||||
#endif /* !_SHA_H */
|
#endif /* !_SHA_H */
|
||||||
|
|
Loading…
Reference in a new issue