@ -82,15 +82,6 @@
* made ) .
*/
# ifndef LITTLE_ENDIAN
# define LITTLE_ENDIAN 1234
# define BIG_ENDIAN 4321
# endif
# ifndef BYTE_ORDER
# define BYTE_ORDER LITTLE_ENDIAN
# endif
# if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
# error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
# endif
@ -104,24 +95,6 @@ typedef uint64_t sha2_word64; /* Exactly 8 bytes */
# define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
# define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
/*** ENDIAN REVERSAL MACROS *******************************************/
# if BYTE_ORDER == LITTLE_ENDIAN
# define REVERSE32(w,x) { \
sha2_word32 tmp = ( w ) ; \
tmp = ( tmp > > 16 ) | ( tmp < < 16 ) ; \
( x ) = ( ( tmp & 0xff00ff00UL ) > > 8 ) | ( ( tmp & 0x00ff00ffUL ) < < 8 ) ; \
}
# define REVERSE64(w,x) { \
sha2_word64 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 */
/*
* Macro for incrementally adding the unsigned 64 - bit integer n to the
* unsigned 128 - bit integer ( represented using a two - element array of
@ -174,9 +147,7 @@ typedef uint64_t sha2_word64; /* Exactly 8 bytes */
* 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 * ) ;
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
@ -201,7 +172,7 @@ static const sha2_word32 K256[64] = {
} ;
/* Initial hash value H for SHA-256: */
static const sha2_word32 sha256_initial_hash_value [ 8 ] = {
const sha2_word32 sha256_initial_hash_value [ 8 ] = {
0x6a09e667UL ,
0xbb67ae85UL ,
0x3c6ef372UL ,
@ -257,7 +228,7 @@ static const sha2_word64 K512[80] = {
} ;
/* Initial hash value H for SHA-512 */
static const sha2_word64 sha512_initial_hash_value [ 8 ] = {
const sha2_word64 sha512_initial_hash_value [ 8 ] = {
0x6a09e667f3bcc908ULL ,
0xbb67ae8584caa73bULL ,
0x3c6ef372fe94f82bULL ,
@ -292,7 +263,7 @@ void sha256_Init(SHA256_CTX* context) {
# if BYTE_ORDER == LITTLE_ENDIAN
# define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
REVERSE32 ( * data + + , W256 [ j ] ) ; \
W256 [ j ] = * data + + ; \
T1 = ( h ) + Sigma1_256 ( e ) + Ch ( ( e ) , ( f ) , ( g ) ) + \
K256 [ j ] + W256 [ j ] ; \
( d ) + = T1 ; \
@ -322,22 +293,21 @@ void sha256_Init(SHA256_CTX* context) {
( h ) = T1 + Sigma0_256 ( a ) + Maj ( ( a ) , ( b ) , ( c ) ) ; \
j + +
void sha256_Transform ( SHA256_CTX * context , const sha2_word32 * data ) {
void sha256_Transform ( const sha2_word32 * state_in , const sha2_word32 * data , sha2_word32 * state_out ) {
sha2_word32 a , b , c , d , e , f , g , h , s0 , s1 ;
sha2_word32 T1 , * W256 ;
sha2_word32 T1 ;
sha2_word32 W256 [ 16 ] ;
int j ;
W256 = ( sha2_word32 * ) context - > buffer ;
/* Initialize registers with the prev. intermediate value */
a = context- > state[ 0 ] ;
b = context- > state[ 1 ] ;
c = context- > state[ 2 ] ;
d = context- > state[ 3 ] ;
e = context- > state[ 4 ] ;
f = context- > state[ 5 ] ;
g = context- > state[ 6 ] ;
h = context- > state[ 7 ] ;
a = state_in [ 0 ] ;
b = state_in [ 1 ] ;
c = state_in [ 2 ] ;
d = state_in [ 3 ] ;
e = state_in [ 4 ] ;
f = state_in [ 5 ] ;
g = state_in [ 6 ] ;
h = state_in [ 7 ] ;
j = 0 ;
do {
@ -365,14 +335,14 @@ void sha256_Transform(SHA256_CTX* context, const sha2_word32* data) {
} while ( j < 64 ) ;
/* Compute the current intermediate hash value */
context- > state [ 0 ] + = a ;
context- > state [ 1 ] + = b ;
context- > state [ 2 ] + = c ;
context- > state [ 3 ] + = d ;
context- > state [ 4 ] + = e ;
context- > state [ 5 ] + = f ;
context- > state [ 6 ] + = g ;
context- > state [ 7 ] + = h ;
state_out[ 0 ] = state_in [ 0 ] + a ;
state_out[ 1 ] = state_in [ 1 ] + b ;
state_out[ 2 ] = state_in [ 2 ] + c ;
state_out[ 3 ] = state_in [ 3 ] + d ;
state_out[ 4 ] = state_in [ 4 ] + e ;
state_out[ 5 ] = state_in [ 5 ] + f ;
state_out[ 6 ] = state_in [ 6 ] + g ;
state_out[ 7 ] = state_in [ 7 ] + h ;
/* Clean up */
a = b = c = d = e = f = g = h = T1 = 0 ;
@ -380,34 +350,25 @@ void sha256_Transform(SHA256_CTX* context, const sha2_word32* data) {
# else /* SHA2_UNROLL_TRANSFORM */
void sha256_Transform ( SHA256_CTX * context , const sha2_word32 * data ) {
void sha256_Transform ( const sha2_word32 * state_in , const sha2_word32 * data , sha2_word32 * state_out ) {
sha2_word32 a , b , c , d , e , f , g , h , s0 , s1 ;
sha2_word32 T1 , T2 , * W256 ;
sha2_word32 T1 , T2 , W256 [ 16 ] ;
int j ;
W256 = ( sha2_word32 * ) ( void * ) context - > buffer ;
/* Initialize registers with the prev. intermediate value */
a = context- > state[ 0 ] ;
b = context- > state[ 1 ] ;
c = context- > state[ 2 ] ;
d = context- > state[ 3 ] ;
e = context- > state[ 4 ] ;
f = context- > state[ 5 ] ;
g = context- > state[ 6 ] ;
h = context- > state[ 7 ] ;
a = state_in [ 0 ] ;
b = state_in [ 1 ] ;
c = state_in [ 2 ] ;
d = state_in [ 3 ] ;
e = state_in [ 4 ] ;
f = state_in [ 5 ] ;
g = state_in [ 6 ] ;
h = state_in [ 7 ] ;
j = 0 ;
do {
# if BYTE_ORDER == LITTLE_ENDIAN
/* Copy data while converting to host byte order */
REVERSE32 ( * data + + , W256 [ j ] ) ;
/* Apply the SHA-256 compression function to update a..h */
T1 = h + Sigma1_256 ( e ) + Ch ( e , f , g ) + K256 [ j ] + W256 [ j ] ;
# else /* BYTE_ORDER == LITTLE_ENDIAN */
/* Apply the SHA-256 compression function to update a..h with copy */
T1 = h + Sigma1_256 ( e ) + Ch ( e , f , g ) + K256 [ j ] + ( W256 [ j ] = * data + + ) ;
# endif /* BYTE_ORDER == LITTLE_ENDIAN */
T2 = Sigma0_256 ( a ) + Maj ( a , b , c ) ;
h = g ;
g = f ;
@ -445,14 +406,14 @@ void sha256_Transform(SHA256_CTX* context, const sha2_word32* data) {
} while ( j < 64 ) ;
/* Compute the current intermediate hash value */
context- > state [ 0 ] + = a ;
context- > state [ 1 ] + = b ;
context- > state [ 2 ] + = c ;
context- > state [ 3 ] + = d ;
context- > state [ 4 ] + = e ;
context- > state [ 5 ] + = f ;
context- > state [ 6 ] + = g ;
context- > state [ 7 ] + = h ;
state_out[ 0 ] = state_in [ 0 ] + a ;
state_out[ 1 ] = state_in [ 1 ] + b ;
state_out[ 2 ] = state_in [ 2 ] + c ;
state_out[ 3 ] = state_in [ 3 ] + d ;
state_out[ 4 ] = state_in [ 4 ] + e ;
state_out[ 5 ] = state_in [ 5 ] + f ;
state_out[ 6 ] = state_in [ 6 ] + g ;
state_out[ 7 ] = state_in [ 7 ] + h ;
/* Clean up */
a = b = c = d = e = f = g = h = T1 = T2 = 0 ;
@ -475,14 +436,20 @@ void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
if ( len > = freespace ) {
/* Fill the buffer completely and process it */
MEMCPY_BCOPY ( & context - > buffer [ usedspace ] , data , freespace ) ;
MEMCPY_BCOPY ( ( ( uint8_t * ) context - > buffer ) + usedspace , data , freespace ) ;
context - > bitcount + = freespace < < 3 ;
len - = freespace ;
data + = freespace ;
sha256_Transform ( context , ( sha2_word32 * ) ( void * ) context - > buffer ) ;
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE32 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
# endif
sha256_Transform ( context - > state , context - > buffer , context - > state ) ;
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY ( & context - > buffer [ usedspace ] , data , len ) ;
MEMCPY_BCOPY ( ( ( uint8_t * ) context - > buffer ) + usedspace , data , len ) ;
context - > bitcount + = len < < 3 ;
/* Clean up: */
usedspace = freespace = 0 ;
@ -491,7 +458,14 @@ void sha256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
}
while ( len > = SHA256_BLOCK_LENGTH ) {
/* Process as many complete blocks as we can */
sha256_Transform ( context , ( sha2_word32 * ) ( void * ) data ) ;
MEMCPY_BCOPY ( context - > buffer , data , SHA256_BLOCK_LENGTH ) ;
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE32 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
# endif
sha256_Transform ( context - > state , context - > buffer , context - > state ) ;
context - > bitcount + = SHA256_BLOCK_LENGTH < < 3 ;
len - = SHA256_BLOCK_LENGTH ;
data + = SHA256_BLOCK_LENGTH ;
@ -512,53 +486,49 @@ void sha256_Final(SHA256_CTX* context, sha2_byte digest[]) {
/* If no digest buffer is passed, we don't bother doing this: */
if ( digest ! = ( sha2_byte * ) 0 ) {
usedspace = ( context - > bitcount > > 3 ) % SHA256_BLOCK_LENGTH ;
/* Begin padding with a 1 bit: */
( ( uint8_t * ) context - > buffer ) [ usedspace + + ] = 0x80 ;
if ( usedspace < = SHA256_SHORT_BLOCK_LENGTH ) {
/* Set-up for the last transform: */
MEMSET_BZERO ( ( ( uint8_t * ) context - > buffer ) + usedspace , SHA256_SHORT_BLOCK_LENGTH - usedspace ) ;
} else {
if ( usedspace < SHA256_BLOCK_LENGTH ) {
MEMSET_BZERO ( ( ( uint8_t * ) context - > buffer ) + usedspace , SHA256_BLOCK_LENGTH - usedspace ) ;
}
# 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 ;
if ( usedspace < = SHA256_SHORT_BLOCK_LENGTH ) {
/* Set-up for the last transform: */
MEMSET_BZERO ( & context - > buffer [ usedspace ] , SHA256_SHORT_BLOCK_LENGTH - usedspace ) ;
} else {
if ( usedspace < SHA256_BLOCK_LENGTH ) {
MEMSET_BZERO ( & context - > buffer [ usedspace ] , SHA256_BLOCK_LENGTH - usedspace ) ;
}
/* Do second-to-last transform: */
sha256_Transform ( context , ( sha2_word32 * ) ( void * ) context - > buffer ) ;
/* And set-up for the last transform: */
MEMSET_BZERO ( context - > buffer , SHA256_SHORT_BLOCK_LENGTH ) ;
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE32 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
} else {
/* Set-up for the last transform: */
# endif
/* Do second-to-last transform: */
sha256_Transform ( context - > state , context - > buffer , context - > state ) ;
/* And set-up for the last transform: */
MEMSET_BZERO ( context - > buffer , SHA256_SHORT_BLOCK_LENGTH ) ;
}
/* Begin padding with a 1 bit: */
* context - > buffer = 0x80 ;
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
for ( int j = 0 ; j < 14 ; j + + ) {
REVERSE32 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
# endif
/* Set the bit count: */
sha2_word64 * t = ( sha2_word64 * ) ( void * ) & context - > buffer [ SHA256_SHORT_BLOCK_LENGTH ] ;
* t = context - > bitcount ;
context- > buffer [ 14 ] = context - > bitcount > > 32 ;
context - > buffer [ 15 ] = context - > bitcount & 0xffffffff ;
/* Final transform: */
sha256_Transform ( context , ( sha2_word32 * ) ( void * ) context - > buffer ) ;
sha256_Transform ( context - > state , context - > buffer , context - > state ) ;
# if BYTE_ORDER == LITTLE_ENDIAN
{
/* Convert TO host byte order */
int j ;
for ( j = 0 ; j < 8 ; j + + ) {
REVERSE32 ( context - > state [ j ] , context - > state [ j ] ) ;
* d + + = context - > state [ j ] ;
}
/* Convert FROM host byte order */
for ( int j = 0 ; j < 8 ; j + + ) {
REVERSE32 ( context - > state [ j ] , context - > state [ j ] ) ;
}
# else
MEMCPY_BCOPY ( d , context - > state , SHA256_DIGEST_LENGTH ) ;
# endif
MEMCPY_BCOPY ( d , context - > state , SHA256_DIGEST_LENGTH ) ;
}
/* Clean up state data: */
@ -615,19 +585,6 @@ void sha512_Init(SHA512_CTX* context) {
# ifdef SHA2_UNROLL_TRANSFORM
/* Unrolled SHA-512 round macros: */
# if BYTE_ORDER == LITTLE_ENDIAN
# define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
REVERSE64 ( * data + + , W512 [ j ] ) ; \
T1 = ( h ) + Sigma1_512 ( e ) + Ch ( ( e ) , ( f ) , ( g ) ) + \
K512 [ j ] + W512 [ j ] ; \
( d ) + = T1 , \
( h ) = T1 + Sigma0_512 ( a ) + Maj ( ( a ) , ( b ) , ( c ) ) , \
j + +
# else /* BYTE_ORDER == LITTLE_ENDIAN */
# define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
T1 = ( h ) + Sigma1_512 ( e ) + Ch ( ( e ) , ( f ) , ( g ) ) + \
K512 [ j ] + ( W512 [ j ] = * data + + ) ; \
@ -635,8 +592,6 @@ void sha512_Init(SHA512_CTX* context) {
( h ) = T1 + Sigma0_512 ( a ) + Maj ( ( a ) , ( b ) , ( c ) ) ; \
j + +
# endif /* BYTE_ORDER == LITTLE_ENDIAN */
# define ROUND512(a,b,c,d,e,f,g,h) \
s0 = W512 [ ( j + 1 ) & 0x0f ] ; \
s0 = sigma0_512 ( s0 ) ; \
@ -648,20 +603,20 @@ void sha512_Init(SHA512_CTX* context) {
( h ) = T1 + Sigma0_512 ( a ) + Maj ( ( a ) , ( b ) , ( c ) ) ; \
j + +
void sha512_Transform ( SHA512_CTX * context , const sha2_word64 * data ) {
void sha512_Transform ( const sha2_word64 * state_in , const sha2_word64 * data , sha2_word64 * state_out ) {
sha2_word64 a , b , c , d , e , f , g , h , s0 , s1 ;
sha2_word64 T1 , * W512 = ( sha2_word64 * ) context - > buffer ;
sha2_word64 T1 , W512 [ 16 ] ;
int j ;
/* Initialize registers with the prev. intermediate value */
a = context- > state[ 0 ] ;
b = context- > state[ 1 ] ;
c = context- > state[ 2 ] ;
d = context- > state[ 3 ] ;
e = context- > state[ 4 ] ;
f = context- > state[ 5 ] ;
g = context- > state[ 6 ] ;
h = context- > state[ 7 ] ;
a = state_in [ 0 ] ;
b = state_in [ 1 ] ;
c = state_in [ 2 ] ;
d = state_in [ 3 ] ;
e = state_in [ 4 ] ;
f = state_in [ 5 ] ;
g = state_in [ 6 ] ;
h = state_in [ 7 ] ;
j = 0 ;
do {
@ -688,14 +643,14 @@ void sha512_Transform(SHA512_CTX* context, const sha2_word64* data) {
} while ( j < 80 ) ;
/* Compute the current intermediate hash value */
context- > state [ 0 ] + = a ;
context- > state [ 1 ] + = b ;
context- > state [ 2 ] + = c ;
context- > state [ 3 ] + = d ;
context- > state [ 4 ] + = e ;
context- > state [ 5 ] + = f ;
context- > state [ 6 ] + = g ;
context- > state [ 7 ] + = h ;
state_out[ 0 ] = state_in [ 0 ] + a ;
state_out[ 1 ] = state_in [ 1 ] + b ;
state_out[ 2 ] = state_in [ 2 ] + c ;
state_out[ 3 ] = state_in [ 3 ] + d ;
state_out[ 4 ] = state_in [ 4 ] + e ;
state_out[ 5 ] = state_in [ 5 ] + f ;
state_out[ 6 ] = state_in [ 6 ] + g ;
state_out[ 7 ] = state_in [ 7 ] + h ;
/* Clean up */
a = b = c = d = e = f = g = h = T1 = 0 ;
@ -703,32 +658,25 @@ void sha512_Transform(SHA512_CTX* context, const sha2_word64* data) {
# else /* SHA2_UNROLL_TRANSFORM */
void sha512_Transform ( SHA512_CTX * context , const sha2_word64 * data ) {
void sha512_Transform ( const sha2_word64 * state_in , const sha2_word64 * data , sha2_word64 * state_out ) {
sha2_word64 a , b , c , d , e , f , g , h , s0 , s1 ;
sha2_word64 T1 , T2 , * W512 = ( sha2_word64 * ) ( void * ) context - > buffer ;
sha2_word64 T1 , T2 , W512 [ 16 ] ;
int j ;
/* Initialize registers with the prev. intermediate value */
a = context- > state[ 0 ] ;
b = context- > state[ 1 ] ;
c = context- > state[ 2 ] ;
d = context- > state[ 3 ] ;
e = context- > state[ 4 ] ;
f = context- > state[ 5 ] ;
g = context- > state[ 6 ] ;
h = context- > state[ 7 ] ;
a = state_in [ 0 ] ;
b = state_in [ 1 ] ;
c = state_in [ 2 ] ;
d = state_in [ 3 ] ;
e = state_in [ 4 ] ;
f = state_in [ 5 ] ;
g = state_in [ 6 ] ;
h = state_in [ 7 ] ;
j = 0 ;
do {
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
REVERSE64 ( * data + + , W512 [ j ] ) ;
/* Apply the SHA-512 compression function to update a..h */
T1 = h + Sigma1_512 ( e ) + Ch ( e , f , g ) + K512 [ j ] + W512 [ j ] ;
# else /* BYTE_ORDER == LITTLE_ENDIAN */
/* Apply the SHA-512 compression function to update a..h with copy */
T1 = h + Sigma1_512 ( e ) + Ch ( e , f , g ) + K512 [ j ] + ( W512 [ j ] = * data + + ) ;
# endif /* BYTE_ORDER == LITTLE_ENDIAN */
T2 = Sigma0_512 ( a ) + Maj ( a , b , c ) ;
h = g ;
g = f ;
@ -766,14 +714,14 @@ void sha512_Transform(SHA512_CTX* context, const sha2_word64* data) {
} while ( j < 80 ) ;
/* Compute the current intermediate hash value */
context- > state [ 0 ] + = a ;
context- > state [ 1 ] + = b ;
context- > state [ 2 ] + = c ;
context- > state [ 3 ] + = d ;
context- > state [ 4 ] + = e ;
context- > state [ 5 ] + = f ;
context- > state [ 6 ] + = g ;
context- > state [ 7 ] + = h ;
state_out[ 0 ] = state_in [ 0 ] + a ;
state_out[ 1 ] = state_in [ 1 ] + b ;
state_out[ 2 ] = state_in [ 2 ] + c ;
state_out[ 3 ] = state_in [ 3 ] + d ;
state_out[ 4 ] = state_in [ 4 ] + e ;
state_out[ 5 ] = state_in [ 5 ] + f ;
state_out[ 6 ] = state_in [ 6 ] + g ;
state_out[ 7 ] = state_in [ 7 ] + h ;
/* Clean up */
a = b = c = d = e = f = g = h = T1 = T2 = 0 ;
@ -796,14 +744,20 @@ void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
if ( len > = freespace ) {
/* Fill the buffer completely and process it */
MEMCPY_BCOPY ( & context - > buffer [ usedspace ] , data , freespace ) ;
MEMCPY_BCOPY ( ( ( uint8_t * ) context - > buffer ) + usedspace , data , freespace ) ;
ADDINC128 ( context - > bitcount , freespace < < 3 ) ;
len - = freespace ;
data + = freespace ;
sha512_Transform ( context , ( sha2_word64 * ) ( void * ) context - > buffer ) ;
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE64 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
# endif
sha512_Transform ( context - > state , context - > buffer , context - > state ) ;
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY ( & context - > buffer [ usedspace ] , data , len ) ;
MEMCPY_BCOPY ( ( ( uint8_t * ) context - > buffer ) + usedspace , data , len ) ;
ADDINC128 ( context - > bitcount , len < < 3 ) ;
/* Clean up: */
usedspace = freespace = 0 ;
@ -812,7 +766,14 @@ void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
}
while ( len > = SHA512_BLOCK_LENGTH ) {
/* Process as many complete blocks as we can */
sha512_Transform ( context , ( sha2_word64 * ) ( void * ) data ) ;
MEMCPY_BCOPY ( context - > buffer , data , SHA512_BLOCK_LENGTH ) ;
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE64 ( ( ( sha2_word64 * ) data ) [ j ] , context - > buffer [ j ] ) ;
}
# endif
sha512_Transform ( context - > state , context - > buffer , context - > state ) ;
ADDINC128 ( context - > bitcount , SHA512_BLOCK_LENGTH < < 3 ) ;
len - = SHA512_BLOCK_LENGTH ;
data + = SHA512_BLOCK_LENGTH ;
@ -826,48 +787,47 @@ void sha512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
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 ;
/* Begin padding with a 1 bit: */
( ( uint8_t * ) context - > buffer ) [ usedspace + + ] = 0x80 ;
if ( usedspace < = SHA512_SHORT_BLOCK_LENGTH ) {
/* Set-up for the last transform: */
MEMSET_BZERO ( ( ( uint8_t * ) context - > buffer ) + usedspace , SHA512_SHORT_BLOCK_LENGTH - usedspace ) ;
} else {
if ( usedspace < SHA512_BLOCK_LENGTH ) {
MEMSET_BZERO ( ( ( uint8_t * ) context - > buffer ) + usedspace , SHA512_BLOCK_LENGTH - usedspace ) ;
}
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64 ( context - > bitcount [ 0 ] , context - > bitcount [ 0 ] ) ;
REVERSE64 ( context - > bitcount [ 1 ] , context - > bitcount [ 1 ] ) ;
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE64 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
# endif
if ( usedspace > 0 ) {
/* Begin padding with a 1 bit: */
context - > buffer [ usedspace + + ] = 0x80 ;
/* Do second-to-last transform: */
sha512_Transform ( context - > state , context - > buffer , context - > state ) ;
if ( usedspace < = SHA512_SHORT_BLOCK_LENGTH ) {
/* Set-up for the last transform: */
MEMSET_BZERO ( & context - > buffer [ usedspace ] , SHA512_SHORT_BLOCK_LENGTH - usedspace ) ;
} else {
if ( usedspace < SHA512_BLOCK_LENGTH ) {
MEMSET_BZERO ( & context - > buffer [ usedspace ] , SHA512_BLOCK_LENGTH - usedspace ) ;
}
/* Do second-to-last transform: */
sha512_Transform ( context , ( sha2_word64 * ) ( void * ) context - > buffer ) ;
/* And set-up for the last transform: */
MEMSET_BZERO ( context - > buffer , SHA512_BLOCK_LENGTH - 2 ) ;
}
} else {
/* Prepare for final transform: */
MEMSET_BZERO ( context - > buffer , SHA512_SHORT_BLOCK_LENGTH ) ;
/* And set-up for the last transform: */
MEMSET_BZERO ( context - > buffer , SHA512_BLOCK_LENGTH - 2 ) ;
}
/* Begin padding with a 1 bit: */
* context - > buffer = 0x80 ;
# if BYTE_ORDER == LITTLE_ENDIAN
/* Convert TO host byte order */
for ( int j = 0 ; j < 16 ; j + + ) {
REVERSE64 ( context - > buffer [ j ] , context - > buffer [ j ] ) ;
}
# endif
/* Store the length of input data (in bits): */
sha2_word64 * t ;
t = ( sha2_word64 * ) ( void * ) & context - > buffer [ SHA512_SHORT_BLOCK_LENGTH ] ;
* t = context - > bitcount [ 1 ] ;
t = ( sha2_word64 * ) ( void * ) & context - > buffer [ SHA512_SHORT_BLOCK_LENGTH + 8 ] ;
* t = context - > bitcount [ 0 ] ;
t = & context - > buffer [ SHA512_SHORT_BLOCK_LENGTH / sizeof ( sha2_word64 ) ] ;
t [ 0 ] = context - > bitcount [ 1 ] ;
t [ 1 ] = context - > bitcount [ 0 ] ;
/* Final transform: */
sha512_Transform ( context , ( sha2_word64 * ) ( void * ) context - > buffer ) ;
sha512_Transform ( context - > state , context - > buffer , context - > state ) ;
}
void sha512_Final ( SHA512_CTX * context , sha2_byte digest [ ] ) {
@ -879,17 +839,12 @@ void sha512_Final(SHA512_CTX* context, sha2_byte digest[]) {
/* Save the hash data for output: */
# if BYTE_ORDER == LITTLE_ENDIAN
{
/* Convert TO host byte order */
int j ;
for ( j = 0 ; j < 8 ; j + + ) {
REVERSE64 ( context - > state [ j ] , context - > state [ j ] ) ;
* d + + = context - > state [ j ] ;
}
/* Convert FROM host byte order */
for ( int j = 0 ; j < 8 ; j + + ) {
REVERSE64 ( context - > state [ j ] , context - > state [ j ] ) ;
}
# else
MEMCPY_BCOPY ( d , context - > state , SHA512_DIGEST_LENGTH ) ;
# endif
MEMCPY_BCOPY ( d , context - > state , SHA512_DIGEST_LENGTH ) ;
}
/* Zero out state data */