Bug #4320 » ruby_issue_4320__digest_sha2_alignment.patch
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;
|