diff -rub ruby-1.9.2-p180/ext/digest/sha2/sha2.c ruby-1.9.2-p180.patched/ext/digest/sha2/sha2.c --- ruby-1.9.2-p180/ext/digest/sha2/sha2.c Wed Jun 16 11:38:14 2010 +++ ruby-1.9.2-p180.patched/ext/digest/sha2/sha2.c Tue Apr 19 15:26:02 2011 @@ -40,6 +40,28 @@ #include "sha2.h" /* + * #if condition from regint.h - XXX there must exist a nicer way + */ + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + (defined(__ppc__) && defined(__APPLE__)) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD86) || \ + defined(__mc68020__) +#define PLAT_NEED_ALIGNED_WORD_ACCESS 0 +#else +#define PLAT_NEED_ALIGNED_WORD_ACCESS 1 +#endif + +/* + * from http://www.wambold.com/Martin/writings/alignof.html + * + * NOTE: This gives us the alignment the compiler would choose, not necessarily + * the minimal alignment requirement for the platform we live on + */ + +#define ALIGNOF(type) offsetof (struct { char c; type member; }, member) + +/* * ASSERT NOTE: * Some sanity checking code is included using assert(). On my FreeBSD * system, this additional code can be removed by compiling with NDEBUG @@ -106,21 +128,7 @@ * 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 */ - -#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 ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) @@ -392,7 +400,7 @@ sha2_word32 T1, *W256; int j; - W256 = (sha2_word32*)context->buffer; + W256 = context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; @@ -450,7 +458,7 @@ sha2_word32 T1, T2, *W256; int j; - W256 = (sha2_word32*)context->buffer; + W256 = context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; @@ -527,6 +535,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; + uint8_t *buffer = (uint8_t *)context->buffer; if (len == 0) { /* Calling with no data is valid - we do nothing */ @@ -537,20 +546,26 @@ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); usedspace = (unsigned int)((context->bitcount >> 3) % SHA256_BLOCK_LENGTH); - if (usedspace > 0) { + + /* work on the buffer if it is filled or if we need to re-align data */ + while (usedspace || ( + PLAT_NEED_ALIGNED_WORD_ACCESS && + (len > 0) && + (((size_t)data % ALIGNOF(sha2_word32)) != 0))) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + MEMCPY_BCOPY(&buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; - SHA256_Transform(context, (sha2_word32*)context->buffer); + SHA256_Transform(context, context->buffer); + usedspace = 0; } else { /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + MEMCPY_BCOPY(&buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; @@ -576,6 +591,7 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; + uint8_t *buffer = (uint8_t *)context->buffer; /* Sanity check: */ assert(context != (SHA256_CTX*)0); @@ -589,17 +605,17 @@ #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; + buffer[usedspace++] = 0x80; if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + MEMSET_BZERO(&buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA256_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + MEMSET_BZERO(&buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); + SHA256_Transform(context, context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); @@ -609,13 +625,13 @@ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; + *buffer = 0x80; } /* Set the bit count: */ - *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + *(sha2_word64*)&buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); + SHA256_Transform(context, context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN { @@ -715,7 +731,7 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + sha2_word64 T1, *W512 = context->buffer; int j; /* Initialize registers with the prev. intermediate value */ @@ -770,7 +786,7 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; - sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + sha2_word64 T1, T2, *W512 = context->buffer; int j; /* Initialize registers with the prev. intermediate value */ @@ -848,6 +864,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; + uint8_t *buffer = (uint8_t *)context->buffer; if (len == 0) { /* Calling with no data is valid - we do nothing */ @@ -855,23 +872,30 @@ } /* Sanity check: */ - assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + assert(context != (SHA512_CTX*)0); + assert(context->buffer != (sha2_word64*)0); + assert(data != (sha2_byte*)0); usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); - if (usedspace > 0) { + /* work on the buffer if it is filled or if we need to re-align data */ + while (usedspace || ( + PLAT_NEED_ALIGNED_WORD_ACCESS && + (len > 0) && + (((size_t)data % ALIGNOF(sha2_word64)) != 0))) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + MEMCPY_BCOPY(&buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; - SHA512_Transform(context, (sha2_word64*)context->buffer); + SHA512_Transform(context, context->buffer); + usedspace = 0; } else { /* The buffer is not yet full */ - MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + MEMCPY_BCOPY(&buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; @@ -896,6 +920,7 @@ void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; + uint8_t *buffer = (uint8_t *)context->buffer; usedspace = (unsigned int)((context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH); #if BYTE_ORDER == LITTLE_ENDIAN @@ -905,17 +930,17 @@ #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; + buffer[usedspace++] = 0x80; if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ - MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + MEMSET_BZERO(&buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA512_BLOCK_LENGTH) { - MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + MEMSET_BZERO(&buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + SHA512_Transform(context, context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); @@ -925,14 +950,14 @@ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; + *buffer = 0x80; } /* Store the length of input data (in bits): */ - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; - *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + *(sha2_word64*)&buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; + *(sha2_word64*)&buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; /* Final transform: */ - SHA512_Transform(context, (sha2_word64*)context->buffer); + SHA512_Transform(context, context->buffer); } void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { diff -rub ruby-1.9.2-p180/ext/digest/sha2/sha2.h ruby-1.9.2-p180.patched/ext/digest/sha2/sha2.h --- ruby-1.9.2-p180/ext/digest/sha2/sha2.h Thu Apr 22 10:04:13 2010 +++ ruby-1.9.2-p180.patched/ext/digest/sha2/sha2.h Tue Apr 19 15:26:02 2011 @@ -119,15 +119,30 @@ * * cc -DSHA2_USE_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 */ + +#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 */ + typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; + sha2_word32 buffer[SHA256_BLOCK_LENGTH / sizeof(sha2_word32)]; } SHA256_CTX; typedef struct _SHA512_CTX { uint64_t state[8]; uint64_t bitcount[2]; - uint8_t buffer[SHA512_BLOCK_LENGTH]; + sha2_word64 buffer[SHA512_BLOCK_LENGTH / sizeof(sha2_word64)]; } SHA512_CTX; typedef SHA512_CTX SHA384_CTX;