summaryrefslogtreecommitdiff
path: root/lib/libc/hash/sha2.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/hash/sha2.c')
-rw-r--r--lib/libc/hash/sha2.c145
1 files changed, 67 insertions, 78 deletions
diff --git a/lib/libc/hash/sha2.c b/lib/libc/hash/sha2.c
index d28a9e32edb..cd95d68064d 100644
--- a/lib/libc/hash/sha2.c
+++ b/lib/libc/hash/sha2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sha2.c,v 1.8 2004/05/05 17:39:47 millert Exp $ */
+/* $OpenBSD: sha2.c,v 1.9 2004/05/07 14:34:40 millert Exp $ */
/*
* FILE: sha2.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "$OpenBSD: sha2.c,v 1.8 2004/05/05 17:39:47 millert Exp $";
+static const char rcsid[] = "$OpenBSD: sha2.c,v 1.9 2004/05/07 14:34:40 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -57,7 +57,6 @@ static const char rcsid[] = "$OpenBSD: sha2.c,v 1.8 2004/05/05 17:39:47 millert
*
*/
-
/*** SHA-256/384/512 Machine Architecture Definitions *****************/
/*
* BYTE_ORDER NOTE:
@@ -97,35 +96,48 @@ static const char rcsid[] = "$OpenBSD: sha2.c,v 1.8 2004/05/05 17:39:47 millert
#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
+/*** ENDIAN SPECIFIC COPY MACROS **************************************/
+#define BE_8_TO_32(dst, cp) do { \
+ (dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) | \
+ ((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24); \
+} while(0)
-/*** ENDIAN REVERSAL MACROS *******************************************/
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define REVERSE32(w,x) { \
- u_int32_t tmp = (w); \
- tmp = (tmp >> 16) | (tmp << 16); \
- (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
-}
-#define REVERSE64(w,x) { \
- u_int64_t tmp = (w); \
- tmp = (tmp >> 32) | (tmp << 32); \
- tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
- ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
- (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
- ((tmp & 0x0000ffff0000ffffULL) << 16); \
-}
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+#define BE_8_TO_64(dst, cp) do { \
+ (dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) | \
+ ((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) | \
+ ((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) | \
+ ((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56); \
+} while (0)
+
+#define BE_64_TO_8(cp, src) do { \
+ (cp)[0] = (src) >> 56; \
+ (cp)[1] = (src) >> 48; \
+ (cp)[2] = (src) >> 40; \
+ (cp)[3] = (src) >> 32; \
+ (cp)[4] = (src) >> 24; \
+ (cp)[5] = (src) >> 16; \
+ (cp)[6] = (src) >> 8; \
+ (cp)[7] = (src); \
+} while (0)
+
+#define BE_32_TO_8(cp, src) do { \
+ (cp)[0] = (src) >> 24; \
+ (cp)[1] = (src) >> 16; \
+ (cp)[2] = (src) >> 8; \
+ (cp)[3] = (src); \
+} while (0)
/*
* Macro for incrementally adding the unsigned 64-bit integer n to the
* unsigned 128-bit integer (represented using a two-element array of
* 64-bit words):
*/
-#define ADDINC128(w,n) { \
- (w)[0] += (u_int64_t)(n); \
- if ((w)[0] < (n)) { \
- (w)[1]++; \
- } \
-}
+#define ADDINC128(w,n) do { \
+ (w)[0] += (u_int64_t)(n); \
+ if ((w)[0] < (n)) { \
+ (w)[1]++; \
+ } \
+} while (0)
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
/*
@@ -279,8 +291,7 @@ SHA256_Init(SHA256_CTX *context)
/* Unrolled SHA-256 round macros: */
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \
- W256[j] = (u_int32_t)data[3] | ((u_int32_t)data[2] << 8) | \
- ((u_int32_t)data[1] << 16) | ((u_int32_t)data[0] << 24); \
+ BE_8_TO_32(W256[j], data); \
data += 4; \
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
(d) += T1; \
@@ -377,8 +388,7 @@ SHA256_Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
j = 0;
do {
- W256[j] = (u_int32_t)data[3] | ((u_int32_t)data[2] << 8) |
- ((u_int32_t)data[1] << 16) | ((u_int32_t)data[0] << 24);
+ BE_8_TO_32(W256[j], data);
data += 4;
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
@@ -486,10 +496,6 @@ SHA256_Pad(SHA256_CTX *context)
unsigned int usedspace;
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Convert FROM host byte order */
- REVERSE64(context->bitcount, context->bitcount);
-#endif
if (usedspace > 0) {
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
@@ -516,8 +522,9 @@ SHA256_Pad(SHA256_CTX *context)
/* Begin padding with a 1 bit: */
*context->buffer = 0x80;
}
- /* Store the length of input data (in bits): */
- *(u_int64_t *)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+ /* Store the length of input data (in bits) in big endian format: */
+ BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
+ context->bitcount);
/* Final transform: */
SHA256_Transform(context->state, context->buffer);
@@ -527,23 +534,20 @@ SHA256_Pad(SHA256_CTX *context)
}
void
-SHA256_Final(u_int8_t digest[], SHA256_CTX *context)
+SHA256_Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *context)
{
- u_int32_t *d = (u_int32_t *)digest;
-
SHA256_Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
/* Convert TO host byte order */
- int j;
- for (j = 0; j < 8; j++) {
- REVERSE32(context->state[j], context->state[j]);
- *d++ = context->state[j];
- }
+ for (i = 0; i < 8; i++)
+ BE_32_TO_8(digest + i * 4, context->state[i]);
#else
- memcpy(d, context->state, SHA256_DIGEST_LENGTH);
+ memcpy(digest, context->state, SHA256_DIGEST_LENGTH);
#endif
}
@@ -569,10 +573,7 @@ SHA512_Init(SHA512_CTX *context)
/* Unrolled SHA-512 round macros: */
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \
- W512[j] = (u_int64_t)data[7] | ((u_int64_t)data[6] << 8) | \
- ((u_int64_t)data[5] << 16) | ((u_int64_t)data[4] << 24) | \
- ((u_int64_t)data[3] << 32) | ((u_int64_t)data[2] << 40) | \
- ((u_int64_t)data[1] << 48) | ((u_int64_t)data[0] << 56); \
+ BE_8_TO_64(W512[j], data); \
data += 8; \
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
(d) += T1; \
@@ -670,10 +671,7 @@ SHA512_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
j = 0;
do {
- W512[j] = (u_int64_t)data[7] | ((u_int64_t)data[6] << 8) |
- ((u_int64_t)data[5] << 16) | ((u_int64_t)data[4] << 24) |
- ((u_int64_t)data[3] << 32) | ((u_int64_t)data[2] << 40) |
- ((u_int64_t)data[1] << 48) | ((u_int64_t)data[0] << 56);
+ BE_8_TO_64(W512[j], data);
data += 8;
/* Apply the SHA-512 compression function to update a..h */
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
@@ -781,11 +779,6 @@ SHA512_Pad(SHA512_CTX *context)
unsigned int usedspace;
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
-#if BYTE_ORDER == LITTLE_ENDIAN
- /* Convert FROM host byte order */
- REVERSE64(context->bitcount[0],context->bitcount[0]);
- REVERSE64(context->bitcount[1],context->bitcount[1]);
-#endif
if (usedspace > 0) {
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
@@ -810,9 +803,11 @@ SHA512_Pad(SHA512_CTX *context)
/* Begin padding with a 1 bit: */
*context->buffer = 0x80;
}
- /* Store the length of input data (in bits): */
- *(u_int64_t *)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
- *(u_int64_t *)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
+ /* Store the length of input data (in bits) in big endian format: */
+ BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],
+ context->bitcount[1]);
+ BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],
+ context->bitcount[0]);
/* Final transform: */
SHA512_Transform(context->state, context->buffer);
@@ -822,23 +817,20 @@ SHA512_Pad(SHA512_CTX *context)
}
void
-SHA512_Final(u_int8_t digest[], SHA512_CTX *context)
+SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context)
{
- u_int64_t *d = (u_int64_t *)digest;
-
SHA512_Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
/* Convert TO host byte order */
- int j;
- for (j = 0; j < 8; j++) {
- REVERSE64(context->state[j],context->state[j]);
- *d++ = context->state[j];
- }
+ for (i = 0; i < 8; i++)
+ BE_64_TO_8(digest + i * 8, context->state[i]);
#else
- memcpy(d, context->state, SHA512_DIGEST_LENGTH);
+ memcpy(digest, context->state, SHA512_DIGEST_LENGTH);
#endif
}
@@ -864,23 +856,20 @@ __weak_alias(SHA384_Update, SHA512_Update);
__weak_alias(SHA384_Pad, SHA512_Pad);
void
-SHA384_Final(u_int8_t digest[], SHA384_CTX *context)
+SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context)
{
- u_int64_t *d = (u_int64_t *)digest;
-
SHA384_Pad(context);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != NULL) {
#if BYTE_ORDER == LITTLE_ENDIAN
+ int i;
+
/* Convert TO host byte order */
- int j;
- for (j = 0; j < 6; j++) {
- REVERSE64(context->state[j],context->state[j]);
- *d++ = context->state[j];
- }
+ for (i = 0; i < 6; i++)
+ BE_64_TO_8(digest + i * 8, context->state[i]);
#else
- memcpy(d, context->state, SHA384_DIGEST_LENGTH);
+ memcpy(digest, context->state, SHA384_DIGEST_LENGTH);
#endif
}