Project

General

Profile

Bug #4320 » ruby_issue_4320__digest_sha2_alignment.patch

slink (Nils Goroll), 04/19/2011 11:49 PM

View differences:

ruby-1.9.2-p180.patched/ext/digest/sha2/sha2.c Tue Apr 19 15:26:02 2011
#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
......
* 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)
......
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];
......
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];
......
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 */
......
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;
......
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);
......
#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);
......
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
{
......
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 */
......
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 */
......
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 */
......
}
/* 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;
......
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
......
#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);
......
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) {
ruby-1.9.2-p180.patched/ext/digest/sha2/sha2.h Tue Apr 19 15:26:02 2011
*
* 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;
(1-1/2)