From e6dde8be4d2538464372fd0c7499d625239a3b08 Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 22 Feb 2010 02:21:22 +0000 Subject: [PATCH] * ext/digest/sha2: Use OpenSSL's SHA1 engine if available. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26726 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 ++ ext/digest/sha2/depend | 1 + ext/digest/sha2/extconf.rb | 16 ++++++-- ext/digest/sha2/sha2.c | 45 +++++---------------- ext/digest/sha2/sha2.h | 83 +++++++++++++------------------------- ext/digest/sha2/sha2init.c | 4 ++ ext/digest/sha2/sha2ossl.c | 11 +++++ ext/digest/sha2/sha2ossl.h | 17 ++++++++ 8 files changed, 85 insertions(+), 96 deletions(-) create mode 100644 ext/digest/sha2/sha2ossl.c create mode 100644 ext/digest/sha2/sha2ossl.h diff --git a/ChangeLog b/ChangeLog index 2114d625f2..c58b9dde1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Mon Feb 22 11:21:18 2010 Nobuyoshi Nakada + + * ext/digest/sha2: Use OpenSSL's SHA1 engine if available. + Sun Feb 21 21:20:17 2010 Nobuyoshi Nakada * lib/mkmf.rb (create_makefile, install_files): honor srcprefix diff --git a/ext/digest/sha2/depend b/ext/digest/sha2/depend index 225d6ad52b..00e18e158d 100644 --- a/ext/digest/sha2/depend +++ b/ext/digest/sha2/depend @@ -3,3 +3,4 @@ sha2.o: sha2.c sha2.h $(srcdir)/../defs.h $(hdrdir)/ruby.h \ sha2init.o: sha2init.c $(srcdir)/../digest.h $(hdrdir)/ruby.h \ $(topdir)/config.h $(hdrdir)/defines.h $(hdrdir)/intern.h \ sha2.h $(srcdir)/../defs.h +sha2ossl.o: sha2ossl.h $(srcdir)/../defs.h diff --git a/ext/digest/sha2/extconf.rb b/ext/digest/sha2/extconf.rb index c15043f113..e546e3ac12 100644 --- a/ext/digest/sha2/extconf.rb +++ b/ext/digest/sha2/extconf.rb @@ -6,10 +6,18 @@ require "mkmf" $defs << "-DHAVE_CONFIG_H" $INCFLAGS << " -I$(srcdir)/.." -$objs = [ - "sha2.#{$OBJEXT}", - "sha2init.#{$OBJEXT}", -] +$objs = [ "sha2init.#{$OBJEXT}" ] + +dir_config("openssl") + +if !with_config("bundled-sha2") && + have_library("crypto") && have_header("openssl/sha.h") && + %w[SHA256 SHA512].all? {|d| have_func("#{d}_Transform", "openssl/sha.h")} + $objs << "sha2ossl.#{$OBJEXT}" +else + have_type("u_int8_t") + $objs << "sha2.#{$OBJEXT}" +end have_header("sys/cdefs.h") diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c index 253e54f265..6e4a99c1e3 100644 --- a/ext/digest/sha2/sha2.c +++ b/ext/digest/sha2/sha2.c @@ -234,7 +234,7 @@ void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ -const static sha2_word32 K256[64] = { +static const sha2_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, @@ -254,7 +254,7 @@ const static sha2_word32 K256[64] = { }; /* Initial hash value H for SHA-256: */ -const static sha2_word32 sha256_initial_hash_value[8] = { +static const sha2_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, @@ -266,7 +266,7 @@ const static sha2_word32 sha256_initial_hash_value[8] = { }; /* Hash constant words K for SHA-384 and SHA-512: */ -const static sha2_word64 K512[80] = { +static const sha2_word64 K512[80] = { ULL(0x428a2f98d728ae22), ULL(0x7137449123ef65cd), ULL(0xb5c0fbcfec4d3b2f), ULL(0xe9b5dba58189dbbc), ULL(0x3956c25bf348b538), ULL(0x59f111f1b605d019), @@ -310,7 +310,7 @@ const static sha2_word64 K512[80] = { }; /* Initial hash value H for SHA-384 */ -const static sha2_word64 sha384_initial_hash_value[8] = { +static const sha2_word64 sha384_initial_hash_value[8] = { ULL(0xcbbb9d5dc1059ed8), ULL(0x629a292a367cd507), ULL(0x9159015a3070dd17), @@ -322,7 +322,7 @@ const static sha2_word64 sha384_initial_hash_value[8] = { }; /* Initial hash value H for SHA-512 */ -const static sha2_word64 sha512_initial_hash_value[8] = { +static const sha2_word64 sha512_initial_hash_value[8] = { ULL(0x6a09e667f3bcc908), ULL(0xbb67ae8584caa73b), ULL(0x3c6ef372fe94f82b), @@ -536,7 +536,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; @@ -573,11 +573,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { usedspace = freespace = 0; } -#ifdef RUBY -void SHA256_Finish(SHA256_CTX* context, sha2_byte digest[]) { -#else void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { -#endif sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; @@ -586,7 +582,7 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); @@ -648,12 +644,7 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) { assert(context != (SHA256_CTX*)0); if (buffer != (char*)0) { -#ifdef RUBY - SHA256_Finish(context, digest); -#else SHA256_Final(digest, context); -#endif - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; @@ -866,7 +857,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { /* Sanity check: */ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; @@ -906,7 +897,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; - usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); @@ -944,11 +935,7 @@ void SHA512_Last(SHA512_CTX* context) { SHA512_Transform(context, (sha2_word64*)context->buffer); } -#ifdef RUBY -void SHA512_Finish(SHA512_CTX* context, sha2_byte digest[]) { -#else void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { -#endif sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ @@ -985,12 +972,7 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) { assert(context != (SHA512_CTX*)0); if (buffer != (char*)0) { -#ifdef RUBY - SHA512_Finish(context, digest); -#else SHA512_Final(digest, context); -#endif - for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; @@ -1027,11 +1009,7 @@ void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { SHA512_Update((SHA512_CTX*)context, data, len); } -#ifdef RUBY -void SHA384_Finish(SHA384_CTX* context, sha2_byte digest[]) { -#else void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { -#endif sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ @@ -1068,12 +1046,7 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) { assert(context != (SHA384_CTX*)0); if (buffer != (char*)0) { -#ifdef RUBY - SHA384_Finish(context, digest); -#else SHA384_Final(digest, context); -#endif - for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; diff --git a/ext/digest/sha2/sha2.h b/ext/digest/sha2/sha2.h index 3536b31330..1231de5ca2 100644 --- a/ext/digest/sha2/sha2.h +++ b/ext/digest/sha2/sha2.h @@ -91,11 +91,18 @@ extern "C" { * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ -#if 0 -typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ -typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ -typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#ifndef SHA2_USE_INTTYPES_H +# ifdef HAVE_U_INT8_T +typedef u_int8_t uint8_t; /* 1-byte (8-bits) */ +typedef u_int32_t uint32_t; /* 4-bytes (32-bits) */ +typedef u_int64_t uint64_t; /* 8-bytes (64-bits) */ +# else +typedef unsigned char uint8_t; /* 1-byte (8-bits) */ +typedef unsigned int uint32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long uint64_t; /* 8-bytes (64-bits) */ +# endif #endif + /* * Most BSD systems already define u_intXX_t types, as does Linux. * Some systems, however, like Compaq's Tru64 Unix instead can use @@ -112,8 +119,6 @@ typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ * * cc -DSHA2_USE_INTTYPES_H ... */ -#ifdef SHA2_USE_INTTYPES_H - typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; @@ -125,21 +130,6 @@ typedef struct _SHA512_CTX { uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; -#else /* SHA2_USE_INTTYPES_H */ - -typedef struct _SHA256_CTX { - u_int32_t state[8]; - u_int64_t bitcount; - u_int8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; -typedef struct _SHA512_CTX { - u_int64_t state[8]; - u_int64_t bitcount[2]; - u_int8_t buffer[SHA512_BLOCK_LENGTH]; -} SHA512_CTX; - -#endif /* SHA2_USE_INTTYPES_H */ - typedef SHA512_CTX SHA384_CTX; @@ -148,70 +138,51 @@ typedef SHA512_CTX SHA384_CTX; #define SHA256_Init rb_Digest_SHA256_Init #define SHA256_Update rb_Digest_SHA256_Update #define SHA256_Finish rb_Digest_SHA256_Finish +#define SHA256_Data rb_Digest_SHA256_Data +#define SHA256_End rb_Digest_SHA256_End +#define SHA256_Last rb_Digest_SHA256_Last +#define SHA256_Transform rb_Digest_SHA256_Transform +#define SHA256_Final(d, c) SHA256_Finish(c, d) #define SHA384_Init rb_Digest_SHA384_Init #define SHA384_Update rb_Digest_SHA384_Update #define SHA384_Finish rb_Digest_SHA384_Finish +#define SHA384_Data rb_Digest_SHA384_Data +#define SHA384_End rb_Digest_SHA384_End +#define SHA384_Last rb_Digest_SHA384_Last +#define SHA384_Transform rb_Digest_SHA384_Transform +#define SHA384_Final(d, c) SHA384_Finish(c, d) #define SHA512_Init rb_Digest_SHA512_Init #define SHA512_Update rb_Digest_SHA512_Update #define SHA512_Finish rb_Digest_SHA512_Finish +#define SHA512_Data rb_Digest_SHA512_Data +#define SHA512_End rb_Digest_SHA512_End +#define SHA512_Last rb_Digest_SHA512_Last +#define SHA512_Transform rb_Digest_SHA512_Transform +#define SHA512_Final(d, c) SHA512_Finish(c, d) #endif /* RUBY */ + #ifndef NOPROTO -#ifdef SHA2_USE_INTTYPES_H void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); -#ifdef RUBY -void SHA256_Finish(SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]); -#else void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -#endif /* RUBY */ char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); -#ifdef RUBY -void SHA384_Finish(SHA384_CTX*, uint8_t[SHA384_DIGEST_LENGTH]); -#else void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -#endif /* RUBY */ char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); -#ifdef RUBY -void SHA512_Finish(SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]); -#else void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -#endif /* RUBY */ char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); -#else /* SHA2_USE_INTTYPES_H */ - -void SHA256_Init(SHA256_CTX *); -void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); -void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); - -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); -void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); - -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); -void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); - -#endif /* SHA2_USE_INTTYPES_H */ - #else /* NOPROTO */ void SHA256_Init(); diff --git a/ext/digest/sha2/sha2init.c b/ext/digest/sha2/sha2init.c index 8b79e950a6..fca33185d8 100644 --- a/ext/digest/sha2/sha2init.c +++ b/ext/digest/sha2/sha2init.c @@ -2,7 +2,11 @@ /* $Id$ */ #include "digest.h" +#if defined(HAVE_OPENSSL_SHA_H) +#include "sha2ossl.h" +#else #include "sha2.h" +#endif #define FOREACH_BITLEN(func) func(256) func(384) func(512) diff --git a/ext/digest/sha2/sha2ossl.c b/ext/digest/sha2/sha2ossl.c new file mode 100644 index 0000000000..86824e72f4 --- /dev/null +++ b/ext/digest/sha2/sha2ossl.c @@ -0,0 +1,11 @@ +#include "defs.h" +#include "sha2ossl.h" + +#define SHA_Finish(bit) \ + void SHA##bit##_Finish(SHA##bit##_CTX *ctx, char *buf) \ + { SHA##bit##_Final((unsigned char *)buf, ctx);} +#define SHA384_Final SHA512_Final + +SHA_Finish(256) +SHA_Finish(384) +SHA_Finish(512) diff --git a/ext/digest/sha2/sha2ossl.h b/ext/digest/sha2/sha2ossl.h new file mode 100644 index 0000000000..4229d14cf9 --- /dev/null +++ b/ext/digest/sha2/sha2ossl.h @@ -0,0 +1,17 @@ +#ifndef SHA2OSSL_H_INCLUDED +#define SHA2OSSL_H_INCLUDED + +#include +#include + +#define SHA256_BLOCK_LENGTH SHA256_CBLOCK +#define SHA384_BLOCK_LENGTH SHA512_CBLOCK +#define SHA512_BLOCK_LENGTH SHA512_CBLOCK + +typedef SHA512_CTX SHA384_CTX; + +void SHA256_Finish(SHA256_CTX *ctx, char *buf); +void SHA384_Finish(SHA384_CTX *ctx, char *buf); +void SHA512_Finish(SHA512_CTX *ctx, char *buf); + +#endif