summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-08 15:35:43 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-08-08 15:35:43 +0000
commit226a7a81d6b824b4d9f4953ef4f9fd8e13fe7964 (patch)
tree68abf9da6a4549d82d3c4f212f04094132cd9bfb /ext
parent217fbb2cf0cebeef643d1c7b5af10eef62658e1f (diff)
merges r24415,r24426,r24427,r24428,r24433,r24434 and r24435 from trunk into ruby_1_9_1.
-- * ext/digest/sha2/sha2.[ch]: Update to 1.0 RELEASE which fixes an off-by-one bug in SHA-256 hashing. Reduce differences from the original while at it. [Bug #1799] -- * ext/digest/sha2/sha2.h (BYTE_ORDER): Define BYTE_ORDER as necessary. [ruby-dev:39029] -- * ext/digest/sha2/sha2.c (*_Final): typos. -- * ext/digest/sha2/lib/sha2.eb: should require sha2.so. -- * ext/digest/*/extconf.rb: inttypes.h and unistd.h need not be checked here. [ruby-dev:39032] -- * ext/digest/sha2/sha2.c: The ULL suffix is not supported by pre-C99 compilers, so resurrect the ULL() macro to regain portability. [ruby-dev:39032] -- Fix a typo. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@24475 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/digest/md5/extconf.rb4
-rw-r--r--ext/digest/rmd160/extconf.rb4
-rw-r--r--ext/digest/sha1/extconf.rb4
-rw-r--r--ext/digest/sha2/extconf.rb4
-rw-r--r--ext/digest/sha2/lib/sha2.rb1
-rw-r--r--ext/digest/sha2/sha2.c280
-rw-r--r--ext/digest/sha2/sha2.h197
7 files changed, 401 insertions, 93 deletions
diff --git a/ext/digest/md5/extconf.rb b/ext/digest/md5/extconf.rb
index 018f8ccb02..ddfdb707f2 100644
--- a/ext/digest/md5/extconf.rb
+++ b/ext/digest/md5/extconf.rb
@@ -20,10 +20,6 @@ end
have_header("sys/cdefs.h")
-have_header("inttypes.h")
-
-have_header("unistd.h")
-
$preload = %w[digest]
create_makefile("digest/md5")
diff --git a/ext/digest/rmd160/extconf.rb b/ext/digest/rmd160/extconf.rb
index 09359944f2..cc361e3d2b 100644
--- a/ext/digest/rmd160/extconf.rb
+++ b/ext/digest/rmd160/extconf.rb
@@ -19,10 +19,6 @@ end
have_header("sys/cdefs.h")
-have_header("inttypes.h")
-
-have_header("unistd.h")
-
$preload = %w[digest]
create_makefile("digest/rmd160")
diff --git a/ext/digest/sha1/extconf.rb b/ext/digest/sha1/extconf.rb
index 87b74c34af..fa9945cd43 100644
--- a/ext/digest/sha1/extconf.rb
+++ b/ext/digest/sha1/extconf.rb
@@ -19,10 +19,6 @@ end
have_header("sys/cdefs.h")
-have_header("inttypes.h")
-
-have_header("unistd.h")
-
$preload = %w[digest]
create_makefile("digest/sha1")
diff --git a/ext/digest/sha2/extconf.rb b/ext/digest/sha2/extconf.rb
index c084a51a64..c15043f113 100644
--- a/ext/digest/sha2/extconf.rb
+++ b/ext/digest/sha2/extconf.rb
@@ -13,10 +13,6 @@ $objs = [
have_header("sys/cdefs.h")
-have_header("inttypes.h")
-
-have_header("unistd.h")
-
$preload = %w[digest]
if have_type("uint64_t", "defs.h", $defs.join(' '))
diff --git a/ext/digest/sha2/lib/sha2.rb b/ext/digest/sha2/lib/sha2.rb
index 52dd639f9b..b8e4609478 100644
--- a/ext/digest/sha2/lib/sha2.rb
+++ b/ext/digest/sha2/lib/sha2.rb
@@ -10,6 +10,7 @@
# $Id$
require 'digest'
+require 'digest/sha2.so'
module Digest
#
diff --git a/ext/digest/sha2/sha2.c b/ext/digest/sha2/sha2.c
index aca9ee926f..253e54f265 100644
--- a/ext/digest/sha2/sha2.c
+++ b/ext/digest/sha2/sha2.c
@@ -1,11 +1,9 @@
/*
- * sha2.c
- *
- * Version 1.0.0beta1
- *
- * Written by Aaron D. Gifford <me@aarongifford.com>
- *
- * Copyright 2000 Aaron D. Gifford. All rights reserved.
+ * FILE: sha2.c
+ * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -19,10 +17,10 @@
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -31,15 +29,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $OrigId: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ * $RoughId: sha2.c,v 1.3 2002/02/26 22:03:36 knu Exp $
+ * $Id$
*/
-/* $RoughId: sha2.c,v 1.3 2002/02/26 22:03:36 knu Exp $ */
-/* $Id$ */
-
-#include "sha2.h"
-#include <stdio.h>
+#include "defs.h"
#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
#include <assert.h> /* assert() */
+#include "sha2.h"
/*
* ASSERT NOTE:
@@ -63,15 +61,64 @@
/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER. If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ * #define LITTLE_ENDIAN 1234
+ * #define BIG_ENDIAN 4321
+ *
+ * And for little-endian machines, add:
+ *
+ * #define BYTE_ORDER LITTLE_ENDIAN
+ *
+ * Or for big-endian machines:
+ *
+ * #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+/*
+ * Define the followingsha2_* types to types of the correct length on
+ * the native archtecture. Most BSD systems and Linux define u_intXX_t
+ * types. Machines with very recent ANSI C headers, can use the
+ * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
+ * during compile or in the sha.h header file.
+ *
+ * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
+ * will need to define these three typedefs below (and the appropriate
+ * ones in sha.h too) by hand according to their system architecture.
+ *
+ * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
+ * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
typedef uint8_t sha2_byte; /* Exactly 1 byte */
typedef uint32_t sha2_word32; /* Exactly 4 bytes */
typedef uint64_t sha2_word64; /* Exactly 8 bytes */
-#if defined(__GNUC__) || defined(_HPUX_SOURCE) || defined(__IBMC__)
-#define ULL(number) number##ULL
-#else
-#define ULL(number) (uint64_t)(number)
-#endif
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef u_int8_t sha2_byte; /* Exactly 1 byte */
+typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
+typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
+
+#endif /* SHA2_USE_INTTYPES_H */
/*** SHA-256/384/512 Various Length Definitions ***********************/
@@ -81,8 +128,13 @@ typedef uint64_t sha2_word64; /* Exactly 8 bytes */
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
+#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__) || defined(_HPUX_SOURCE) || defined(__IBMC__)
+#define ULL(number) number##ULL
+#else
+#define ULL(number) (uint64_t)(number)
+#endif
/*** ENDIAN REVERSAL MACROS *******************************************/
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
#define REVERSE32(w,x) { \
sha2_word32 tmp = (w); \
tmp = (tmp >> 16) | (tmp << 16); \
@@ -96,7 +148,7 @@ typedef uint64_t sha2_word64; /* Exactly 8 bytes */
(x) = ((tmp & ULL(0xffff0000ffff0000)) >> 16) | \
((tmp & ULL(0x0000ffff0000ffff)) << 16); \
}
-#endif
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
/*
* Macro for incrementally adding the unsigned 64-bit integer n to the
@@ -281,6 +333,12 @@ const static sha2_word64 sha512_initial_hash_value[8] = {
ULL(0x5be0cd19137e2179)
};
+/*
+ * Constant used by SHA256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char *sha2_hex_digits = "0123456789abcdef";
+
/*** SHA-256: *********************************************************/
void SHA256_Init(SHA256_CTX* context) {
@@ -296,7 +354,7 @@ void SHA256_Init(SHA256_CTX* context) {
/* Unrolled SHA-256 round macros: */
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
REVERSE32(*data++, W256[j]); \
@@ -307,7 +365,7 @@ void SHA256_Init(SHA256_CTX* context) {
j++
-#else
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
@@ -316,7 +374,7 @@ void SHA256_Init(SHA256_CTX* context) {
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
j++
-#endif
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
#define ROUND256(a,b,c,d,e,f,g,h) \
s0 = W256[(j+1)&0x0f]; \
@@ -406,15 +464,15 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
j = 0;
do {
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
/* Copy data while converting to host byte order */
REVERSE32(*data++,W256[j]);
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
-#else
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
/* Apply the SHA-256 compression function to update a..h with copy */
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
-#endif
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
T2 = Sigma0_256(a) + Maj(a, b, c);
h = g;
g = f;
@@ -476,7 +534,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
}
/* Sanity check: */
- assert(context != NULL && data != NULL);
+ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
if (usedspace > 0) {
@@ -501,7 +559,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
}
while (len >= SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA256_Transform(context, (const sha2_word32*)data);
+ SHA256_Transform(context, (sha2_word32*)data);
context->bitcount += SHA256_BLOCK_LENGTH << 3;
len -= SHA256_BLOCK_LENGTH;
data += SHA256_BLOCK_LENGTH;
@@ -515,17 +573,21 @@ 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;
/* Sanity check: */
- assert(context != NULL);
+ assert(context != (SHA256_CTX*)0);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte*)0) {
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->bitcount,context->bitcount);
#endif
@@ -559,7 +621,7 @@ void SHA256_Finish(SHA256_CTX* context, sha2_byte digest[]) {
/* Final transform: */
SHA256_Transform(context, (sha2_word32*)context->buffer);
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
{
/* Convert TO host byte order */
int j;
@@ -574,10 +636,46 @@ void SHA256_Finish(SHA256_CTX* context, sha2_byte digest[]) {
}
/* Clean up state data: */
- MEMSET_BZERO(context, sizeof(SHA256_CTX));
+ MEMSET_BZERO(context, sizeof(context));
usedspace = 0;
}
+char *SHA256_End(SHA256_CTX* context, char buffer[]) {
+ sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ 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];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(context));
+ }
+ MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
+ SHA256_CTX context;
+
+ SHA256_Init(&context);
+ SHA256_Update(&context, data, len);
+ return SHA256_End(&context, digest);
+}
+
+
/*** SHA-512: *********************************************************/
void SHA512_Init(SHA512_CTX* context) {
if (context == (SHA512_CTX*)0) {
@@ -591,7 +689,7 @@ void SHA512_Init(SHA512_CTX* context) {
#ifdef SHA2_UNROLL_TRANSFORM
/* Unrolled SHA-512 round macros: */
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
REVERSE64(*data++, W512[j]); \
@@ -602,7 +700,7 @@ void SHA512_Init(SHA512_CTX* context) {
j++
-#else
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
@@ -611,7 +709,7 @@ void SHA512_Init(SHA512_CTX* context) {
(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
j++
-#endif
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
#define ROUND512(a,b,c,d,e,f,g,h) \
s0 = W512[(j+1)&0x0f]; \
@@ -696,15 +794,15 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
j = 0;
do {
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
REVERSE64(*data++, W512[j]);
/* Apply the SHA-512 compression function to update a..h */
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
-#else
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
/* Apply the SHA-512 compression function to update a..h with copy */
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
-#endif
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
T2 = Sigma0_512(a) + Maj(a, b, c);
h = g;
g = f;
@@ -766,7 +864,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
}
/* Sanity check: */
- assert(context != NULL && data != NULL);
+ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
if (usedspace > 0) {
@@ -779,7 +877,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
ADDINC128(context->bitcount, freespace << 3);
len -= freespace;
data += freespace;
- SHA512_Transform(context, (const sha2_word64*)context->buffer);
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
@@ -791,7 +889,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
}
while (len >= SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA512_Transform(context, (const sha2_word64*)data);
+ SHA512_Transform(context, (sha2_word64*)data);
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
len -= SHA512_BLOCK_LENGTH;
data += SHA512_BLOCK_LENGTH;
@@ -809,7 +907,7 @@ void SHA512_Last(SHA512_CTX* context) {
unsigned int usedspace;
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->bitcount[0],context->bitcount[0]);
REVERSE64(context->bitcount[1],context->bitcount[1]);
@@ -826,7 +924,7 @@ void SHA512_Last(SHA512_CTX* context) {
MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
- SHA512_Transform(context, (const sha2_word64*)context->buffer);
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
/* And set-up for the last transform: */
MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
@@ -843,21 +941,25 @@ void SHA512_Last(SHA512_CTX* context) {
*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
/* Final transform: */
- SHA512_Transform(context, (const sha2_word64*)context->buffer);
+ 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: */
- assert(context != NULL);
+ assert(context != (SHA512_CTX*)0);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte*)0) {
SHA512_Last(context);
/* Save the hash data for output: */
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
{
/* Convert TO host byte order */
int j;
@@ -872,9 +974,45 @@ void SHA512_Finish(SHA512_CTX* context, sha2_byte digest[]) {
}
/* Zero out state data */
- MEMSET_BZERO(context, sizeof(SHA512_CTX));
+ MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA512_End(SHA512_CTX* context, char buffer[]) {
+ sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ 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];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(context));
+ }
+ MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
+ SHA512_CTX context;
+
+ SHA512_Init(&context);
+ SHA512_Update(&context, data, len);
+ return SHA512_End(&context, digest);
}
+
/*** SHA-384: *********************************************************/
void SHA384_Init(SHA384_CTX* context) {
if (context == (SHA384_CTX*)0) {
@@ -889,18 +1027,22 @@ 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: */
- assert(context != NULL);
+ assert(context != (SHA384_CTX*)0);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte*)0) {
SHA512_Last((SHA512_CTX*)context);
/* Save the hash data for output: */
-#ifndef WORDS_BIGENDIAN
+#if BYTE_ORDER == LITTLE_ENDIAN
{
/* Convert TO host byte order */
int j;
@@ -915,5 +1057,41 @@ void SHA384_Finish(SHA384_CTX* context, sha2_byte digest[]) {
}
/* Zero out state data */
- MEMSET_BZERO(context, sizeof(SHA384_CTX));
+ MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA384_End(SHA384_CTX* context, char buffer[]) {
+ sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ 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];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(context));
+ }
+ MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
+ SHA384_CTX context;
+
+ SHA384_Init(&context);
+ SHA384_Update(&context, data, len);
+ return SHA384_End(&context, digest);
}
+
diff --git a/ext/digest/sha2/sha2.h b/ext/digest/sha2/sha2.h
index 917d415b73..3536b31330 100644
--- a/ext/digest/sha2/sha2.h
+++ b/ext/digest/sha2/sha2.h
@@ -1,11 +1,9 @@
/*
- * sha2.h
- *
- * Version 1.0.0beta1
- *
- * Written by Aaron D. Gifford <me@aarongifford.com>
- *
- * Copyright 2000 Aaron D. Gifford. All rights reserved.
+ * FILE: sha2.h
+ * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -19,10 +17,10 @@
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -31,11 +29,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * $OrigId: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ * $RoughId: sha2.h,v 1.3 2002/02/24 08:14:32 knu Exp $
+ * $Id$
*/
-/* $RoughId: sha2.h,v 1.3 2002/02/24 08:14:32 knu Exp $ */
-/* $Id$ */
-
#ifndef __SHA2_H__
#define __SHA2_H__
@@ -43,7 +41,37 @@
extern "C" {
#endif
-#include "defs.h"
+
+/*
+ * Import u_intXX_t size_t type definitions from system headers. You
+ * may need to change this, or define these things yourself in this
+ * file.
+ */
+#include <sys/types.h>
+
+#ifdef RUBY
+# ifdef HAVE_PROTOTYPES
+# undef NOPROTO
+# else
+# define NOPROTO
+# endif /* HAVE_PROTOTYPES */
+# ifndef BYTE_ORDER
+# define LITTLE_ENDIAN 1234
+# define BIG_ENDIAN 4321
+# ifdef WORDS_BIGENDIAN
+# define BYTE_ORDER BIG_ENDIAN
+# else
+# define BYTE_ORDER LITTLE_ENDIAN
+# endif
+# endif /* BYTE_ORDER */
+# define SHA2_USE_INTTYPES_H
+#else /* RUBY */
+#ifdef SHA2_USE_INTTYPES_H
+
+#include <inttypes.h>
+
+#endif /* SHA2_USE_INTTYPES_H */
+#endif /* RUBY */
/*** SHA-256/384/512 Various Length Definitions ***********************/
@@ -59,6 +87,32 @@ extern "C" {
/*** SHA-256/384/512 Context Structures *******************************/
+/* NOTE: If your architecture does not define either u_intXX_t types or
+ * 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) */
+#endif
+/*
+ * Most BSD systems already define u_intXX_t types, as does Linux.
+ * Some systems, however, like Compaq's Tru64 Unix instead can use
+ * uintXX_t types defined by very recent ANSI C standards and included
+ * in the file:
+ *
+ * #include <inttypes.h>
+ *
+ * If you choose to use <inttypes.h> then please define:
+ *
+ * #define SHA2_USE_INTTYPES_H
+ *
+ * Or on the command line during compile:
+ *
+ * cc -DSHA2_USE_INTTYPES_H ...
+ */
+#ifdef SHA2_USE_INTTYPES_H
typedef struct _SHA256_CTX {
uint32_t state[8];
@@ -71,9 +125,25 @@ 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;
+/*** SHA-256/384/512 Function Prototypes ******************************/
#ifdef RUBY
#define SHA256_Init rb_Digest_SHA256_Init
#define SHA256_Update rb_Digest_SHA256_Update
@@ -86,20 +156,95 @@ typedef SHA512_CTX SHA384_CTX;
#define SHA512_Init rb_Digest_SHA512_Init
#define SHA512_Update rb_Digest_SHA512_Update
#define SHA512_Finish rb_Digest_SHA512_Finish
-#endif
+#endif /* RUBY */
+#ifndef NOPROTO
+#ifdef SHA2_USE_INTTYPES_H
-/*** SHA-256/384/512 Function Prototypes ******************************/
-void SHA256_Init _((SHA256_CTX *));
-void SHA256_Update _((SHA256_CTX*, const uint8_t*, size_t));
-void SHA256_Finish _((SHA256_CTX*, uint8_t[SHA256_DIGEST_LENGTH]));
-
-void SHA384_Init _((SHA384_CTX*));
-void SHA384_Update _((SHA384_CTX*, const uint8_t*, size_t));
-void SHA384_Finish _((SHA384_CTX*, uint8_t[SHA384_DIGEST_LENGTH]));
-
-void SHA512_Init _((SHA512_CTX*));
-void SHA512_Update _((SHA512_CTX*, const uint8_t*, size_t));
-void SHA512_Finish _((SHA512_CTX*, uint8_t[SHA512_DIGEST_LENGTH]));
+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();
+void SHA256_Update();
+#ifdef RUBY
+void SHA256_Finish();
+#else
+void SHA256_Final();
+#endif /* RUBY */
+char* SHA256_End();
+char* SHA256_Data();
+
+void SHA384_Init();
+void SHA384_Update();
+#ifdef RUBY
+void SHA384_Finish();
+#else
+void SHA384_Final();
+#endif /* RUBY */
+char* SHA384_End();
+char* SHA384_Data();
+
+void SHA512_Init();
+void SHA512_Update();
+#ifdef RUBY
+void SHA512_Finish();
+#else
+void SHA512_Final();
+#endif /* RUBY */
+char* SHA512_End();
+char* SHA512_Data();
+
+#endif /* NOPROTO */
#ifdef __cplusplus
}