diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-05-07 14:34:41 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-05-07 14:34:41 +0000 |
commit | 9e627b5468b618eb1d7017e092537c41b3507daa (patch) | |
tree | c8145b9506230081722784a72447442a38eedf9e | |
parent | 03a40edceeae04970b47cd3234f0320fa3ce4d71 (diff) |
Simpler byte order flipping. Now the only place we explicitly check
for the host byte order is when we copy the final digest (and that
is just an optimization).
-rw-r--r-- | lib/libc/hash/sha2.c | 145 |
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 } |