*
* $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
*/
+#include <config.h>
+#include <endian.h>
#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
#include <assert.h> /* assert() */
#include "sha2_internal.h"
* 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.
+ * equivalent.
*
* If your system does not define the above, then you can do so by
* hand like this:
/*** ENDIAN REVERSAL MACROS *******************************************/
#if BYTE_ORDER == LITTLE_ENDIAN
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define REVERSE32(w,x) { \
+ (x) = __builtin_bswap32(w); \
+}
+#define REVERSE64(w,x) { \
+ (x) = __builtin_bswap64(w); \
+}
+#else
#define REVERSE32(w,x) { \
sha2_word32 tmp = (w); \
tmp = (tmp >> 16) | (tmp << 16); \
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
((tmp & 0x0000ffff0000ffffULL) << 16); \
}
+#endif
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
/*
* library -- they are intended for private internal visibility/use
* only.
*/
-void SHA512_Last(SHA512_CTX*);
-void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
-void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+static void SHA512_Last(SHA512_CTX*);
+static void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
+static void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
j++
-void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
sha2_word32 T1, *W256;
int j;
#else /* SHA2_UNROLL_TRANSFORM */
-void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
sha2_word32 T1, T2, *W256;
int j;
}
while (len >= SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA256_Transform(context, (sha2_word32*)data);
+ sha2_byte buffer[SHA256_BLOCK_LENGTH];
+ MEMCPY_BCOPY(buffer, data, SHA256_BLOCK_LENGTH);
+ SHA256_Transform(context, (sha2_word32*)buffer);
context->bitcount += SHA256_BLOCK_LENGTH << 3;
len -= SHA256_BLOCK_LENGTH;
data += SHA256_BLOCK_LENGTH;
*context->buffer = 0x80;
}
/* Set the bit count: */
- *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+ union {
+ sha2_byte* c;
+ sha2_word64* l;
+ } bitcount;
+ bitcount.c = &context->buffer[SHA256_SHORT_BLOCK_LENGTH];
+ *(bitcount.l) = context->bitcount;
/* Final transform: */
SHA256_Transform(context, (sha2_word32*)context->buffer);
}
/* Clean up state data: */
- MEMSET_BZERO(context, sizeof(context));
+ MEMSET_BZERO(context, sizeof(*context));
usedspace = 0;
}
}
*buffer = (char)0;
} else {
- MEMSET_BZERO(context, sizeof(context));
+ MEMSET_BZERO(context, sizeof(*context));
}
MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
return buffer;
(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
j++
-void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+static 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;
int j;
#else /* SHA2_UNROLL_TRANSFORM */
-void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+static 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;
int j;
}
while (len >= SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA512_Transform(context, (sha2_word64*)data);
+ sha2_byte buffer[SHA512_BLOCK_LENGTH];
+ MEMCPY_BCOPY(buffer, data, SHA512_BLOCK_LENGTH);
+ SHA512_Transform(context, (sha2_word64*)buffer);
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
len -= SHA512_BLOCK_LENGTH;
data += SHA512_BLOCK_LENGTH;
usedspace = freespace = 0;
}
-void SHA512_Last(SHA512_CTX* context) {
+static void SHA512_Last(SHA512_CTX* context) {
unsigned int usedspace;
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
*context->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];
+ union {
+ sha2_byte* c;
+ sha2_word64* l;
+ } bitcount;
+ bitcount.c = &context->buffer[SHA512_SHORT_BLOCK_LENGTH];
+ bitcount.l[0] = context->bitcount[1];
+ bitcount.l[1] = context->bitcount[0];
/* Final transform: */
SHA512_Transform(context, (sha2_word64*)context->buffer);
}
/* Zero out state data */
- MEMSET_BZERO(context, sizeof(context));
+ MEMSET_BZERO(context, sizeof(*context));
}
char *SHA512_End(SHA512_CTX* context, char buffer[]) {
}
*buffer = (char)0;
} else {
- MEMSET_BZERO(context, sizeof(context));
+ MEMSET_BZERO(context, sizeof(*context));
}
MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
return buffer;
}
/* Zero out state data */
- MEMSET_BZERO(context, sizeof(context));
+ MEMSET_BZERO(context, sizeof(*context));
}
char *SHA384_End(SHA384_CTX* context, char buffer[]) {
}
*buffer = (char)0;
} else {
- MEMSET_BZERO(context, sizeof(context));
+ MEMSET_BZERO(context, sizeof(*context));
}
MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
return buffer;