[ESRG-CVS] sfesrg/esrgpcpj/shared/c_datd esrg_sha512.c,1.2,1.3
Brought to you by:
dtashley
|
From: David T. A. <dta...@us...> - 2009-11-28 18:17:11
|
Update of /cvsroot/esrg/sfesrg/esrgpcpj/shared/c_datd In directory sfp-cvsdas-1.v30.ch3.sourceforge.com:/tmp/cvs-serv14969/shared/c_datd Modified Files: esrg_sha512.c Log Message: Development edits. Index: esrg_sha512.c =================================================================== RCS file: /cvsroot/esrg/sfesrg/esrgpcpj/shared/c_datd/esrg_sha512.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** esrg_sha512.c 28 Nov 2009 06:56:28 -0000 1.2 --- esrg_sha512.c 28 Nov 2009 18:17:03 -0000 1.3 *************** *** 106,131 **** //Copy the buffer contents into the words. We need to be careful //to do this correctly, because of big-endian/little-endian concerns. for (i=0; i<16; i++) { assert((i * 8 + 3) < 128); ! arg->M[i] = (((unsigned __int64)(arg->buf[i*8+7])) << 56) + ! (((unsigned __int64)(arg->buf[i*8+6])) << 48) + ! (((unsigned __int64)(arg->buf[i*8+5])) << 40) + ! (((unsigned __int64)(arg->buf[i*8+4])) << 32) + ! (((unsigned __int64)(arg->buf[i*8+3])) << 24) + ! (((unsigned __int64)(arg->buf[i*8+2])) << 16) + ! (((unsigned __int64)(arg->buf[i*8+1])) << 8) + ! (((unsigned __int64)(arg->buf[i*8]))); } } //Does the SHA-512 rounds as specified by FIPS 180-3. --- 106,209 ---- //Copy the buffer contents into the words. We need to be careful //to do this correctly, because of big-endian/little-endian concerns. + //From FIPS 180-3 (alluded to, not really stated), the message is + //loaded in from M[0] down to M[15]. Additionally, per the other + //conventions in the document, the first byte is uppermost in each + //word. for (i=0; i<16; i++) { assert((i * 8 + 3) < 128); ! arg->M[i] = (((unsigned __int64)(arg->buf[i*8+0])) << 56) + ! (((unsigned __int64)(arg->buf[i*8+1])) << 48) + ! (((unsigned __int64)(arg->buf[i*8+2])) << 40) + ! (((unsigned __int64)(arg->buf[i*8+3])) << 32) + ! (((unsigned __int64)(arg->buf[i*8+4])) << 24) + ! (((unsigned __int64)(arg->buf[i*8+5])) << 16) + ! (((unsigned __int64)(arg->buf[i*8+6])) << 8) + ! (((unsigned __int64)(arg->buf[i*8+7]))); ! } ! } ! ! //Copies out the buffer of words into a string buffer of string length 128, and also places ! //the zero terminator, which means that the string supplied by the caller must be of size ! //129 or larger. ! // ! static void ESRG_SHA512_CopyWordsToStringBuffer(struct ESRG_SHA512_Sha512StateStruct *arg, ! char *buf) ! { ! unsigned int i, j; ! unsigned char *puc; ! unsigned __int64 woi; ! ! assert(arg != NULL); ! assert(buf != NULL); ! ! //Copy the buffer contents into the words. We need to be careful ! //to do this correctly, because of big-endian/little-endian concerns. ! //From FIPS 180-3 (alluded to, not really stated), the message is ! //loaded in from M[0] down to M[15]. Additionally, per the other ! //conventions in the document, the first byte is uppermost in each ! //word. ! for (i=0; i<8; i++) ! { ! //Grab the correct word. In retrospect, the H0 ... H7 variables ! //probably should have been an array. ! // ! switch(i) ! { ! default: ! assert(0); ! break; ! case 0: ! woi = arg->H0; ! break; ! case 1: ! woi = arg->H1; ! break; ! case 2: ! woi = arg->H2; ! break; ! case 3: ! woi = arg->H3; ! break; ! case 4: ! woi = arg->H4; ! break; ! case 5: ! woi = arg->H5; ! break; ! case 6: ! woi = arg->H6; ! break; ! case 7: ! woi = arg->H7; ! break; ! } ! ! //Form a pointer to the buffer location of interest. We work ! //backwards. ! puc = (unsigned char *)buf + (i * 16) + 15; ! ! //Fill in the buffer. ! for (j=0; j<16; j++) ! { ! *puc = (unsigned char)CHARFUNC_nibble_to_lc_hex_digit((int)(woi & 0xF)); ! woi >>= 4; ! puc--; ! } } + + //Place the zero string terminator. + buf[128] = 0; } + //Does the SHA-512 rounds as specified by FIPS 180-3. *************** *** 268,275 **** ! void ESRG_SHA512_Sha512StateStructAddData(struct ESRG_SHA512_Sha512StateStruct *arg, ! void *pointer_in, ! unsigned len) { } --- 346,387 ---- ! void ESRG_SHA512_Sha512StateStructAddData(struct ESRG_SHA512_Sha512StateStruct *arg, ! void *pointer_in, ! unsigned len) { + unsigned int low_32; + unsigned int byte_offset; + unsigned char *data; + + assert(arg != NULL); + assert(pointer_in != NULL); + + data = (unsigned char *)pointer_in; + //It is easier to do it this way, rather than cast all the time. + + low_32 = (unsigned int)arg->bit_count; + //Copy off the least significant bits. Easier to do once. We only + //need the 32 least significant because the block size is 0 modulo 1024. + + byte_offset = low_32 >> 3; + //This gives our byte offset, up to 500+Mb or so. + + while(len--) + { + //We process rounds AFTER a byte is added to the buffer. So + //it is always safe to add a byte first. + arg->buf[byte_offset & 0x7F] = *data; + + //Nothing to do unless this was the final byte of the buffer. + if ((byte_offset & 0x7F) == 127) + { + ESRG_SHA512_DoSha512Rounds(arg); + } + + //Increment. + data++; + byte_offset++; + arg->bit_count += 8; + } } *************** *** 278,287 **** struct ESRG_SHA512_Sha512ResultStruct *result) { ! unsigned i; - for (i=0; i<128; i++) - result->sha512_chars[i] = 'X'; ! result->sha512_chars[128] = 0; } --- 390,541 ---- struct ESRG_SHA512_Sha512ResultStruct *result) { ! #if 0 ! unsigned int low_32, high_32, high_32_copy, low_32_copy; ! unsigned int byte_offset; ! unsigned int buffer_offset; ! unsigned char length_buf[8]; ! //int i; ! //Obtain easier-to-use indices. These provide a snapshot of the ! //length before padding is done. ! low_32 = (unsigned int)state->bit_count; ! high_32 = (unsigned int)(state->bit_count >> 32); ! byte_offset = low_32 >> 3; ! buffer_offset = byte_offset & 0x3F; ! ! //We need to pad the buffer out to 8 bytes short of a multiple, ! //per RFC 1321. ! ESRG_MD5_Md5StateStructAddData(state, ! ESRG_MD5_pad_table, ! (buffer_offset==56) ? (64) : ((56 - buffer_offset) & 0x3F)); ! ! //At this point we are fully prepped to stuff in the length in bits. ! //Prepare the length in a buffer. ! high_32_copy = high_32; ! low_32_copy = low_32; ! length_buf[0] = (unsigned char)(low_32_copy); ! length_buf[1] = (unsigned char)(low_32_copy >> 8); ! length_buf[2] = (unsigned char)(low_32_copy >> 16); ! length_buf[3] = (unsigned char)(low_32_copy >> 24); ! length_buf[4] = (unsigned char)(high_32_copy); ! length_buf[5] = (unsigned char)(high_32_copy >> 8); ! length_buf[6] = (unsigned char)(high_32_copy >> 16); ! length_buf[7] = (unsigned char)(high_32_copy >> 24); ! ! //Tack on the length. This is guaranteed to generate end up with ! //the last thing being done the compute plus the index being zero. ! // ! ESRG_MD5_Md5StateStructAddData(state, ! length_buf, ! 8); ! ! //Be absolutely sure we are rolled over to zero. ! assert((((int)state->bit_count) & 0x1FF) == 0); ! ! //Zero out the return state, just to be sure. ! memset(result, 0, sizeof(struct ESRG_MD5_Md5ResultStruct)); ! ! //Give caller the binary version. ! result->md5_words[0] = state->A; ! result->md5_words[1] = state->B; ! result->md5_words[2] = state->C; ! result->md5_words[3] = state->D; ! ! //Convert to string for caller. ! CHARFUNC_int_to_lc_hex_rev(state->A, result->md5_chars + 0); ! CHARFUNC_int_to_lc_hex_rev(state->B, result->md5_chars + 8); ! CHARFUNC_int_to_lc_hex_rev(state->C, result->md5_chars + 16); ! CHARFUNC_int_to_lc_hex_rev(state->D, result->md5_chars + 24); ! ! //Because of the way the CHARFUNC_int_to_lc_hex_rev() function ! //works, it produces the mirror image of the sequence of nibbles. ! //This is not quite what we want. What we want (least significant ! //byte first, but within each byte most significant nibble first) ! //from each integer is this: ! // ! // n1 n0 n3 n2 n5 n4 n7 n6 ! // ! //but what we get from that function is this: ! // ! // n0 n1 n2 n3 n4 n5 n6 n6, ! // ! //so we have to swap nibbles in each byte. ! // ! { ! int i; ! char temp; ! ! for (i=0; i<16; i++) ! { ! temp = result->md5_chars[i*2]; ! result->md5_chars[i*2] = result->md5_chars[i*2+1]; ! result->md5_chars[i*2+1] = temp; ! } ! } ! ! result->md5_chars[32] = 0; //Terminator. ! ! //Destroy the state, which may contain sensitive information. ! //This idea came from Rivest's sample code. ! memset(state, 0, sizeof(struct ESRG_MD5_Md5StateStruct)); ! ! #endif ! ! unsigned __int64 msglen; ! //Used to hold message length before we pad the message. ! unsigned char c01 = 0x80; ! //Used to append the "1" per FIPS 180-3. ! unsigned char c00 = 0x00; ! //Used to add 0's per FIPS 180-3. ! unsigned char length_buf[16]; ! //Buffer used to form the message length and append it to the message per FIPS 180-3. ! ! //Be sure the input pointers aren't obviously invalid. ! assert(state != NULL); ! assert(result != NULL); ! ! //Snapshot the message length. We'll be changing it when we pad the message. ! msglen = state->bit_count; ! ! //Add the required "1" to the end of the message, per FIPS 180-3. Because ! //this software module only allows the addition of bytes (not bits), adding the ! //"1" will always involve adding the byte 0x80. ! ESRG_SHA512_Sha512StateStructAddData(state, &c01, 1); ! ! //Add enough 0's to the message so that we have exactly room for 16 bytes (128 bits) ! //of length information at the end of the message. ! while ((state->bit_count & 0x3FF) != 896) ! ESRG_SHA512_Sha512StateStructAddData(state, &c00, 1); ! ! //Calculate the length as a series of bytes. ! length_buf[15] = 0; ! length_buf[14] = 0; ! length_buf[13] = 0; ! length_buf[12] = 0; ! length_buf[11] = 0; ! length_buf[10] = 0; ! length_buf[ 9] = 0; ! length_buf[ 8] = 0; ! length_buf[ 7] = (unsigned char)((msglen >> 56) & 0xFF); ! length_buf[ 6] = (unsigned char)((msglen >> 48) & 0xFF);; ! length_buf[ 5] = (unsigned char)((msglen >> 40) & 0xFF);; ! length_buf[ 4] = (unsigned char)((msglen >> 32) & 0xFF);; ! length_buf[ 3] = (unsigned char)((msglen >> 24) & 0xFF);; ! length_buf[ 2] = (unsigned char)((msglen >> 16) & 0xFF);; ! length_buf[ 1] = (unsigned char)((msglen >> 8) & 0xFF);; ! length_buf[ 0] = (unsigned char)((msglen) & 0xFF);; ! ! //Add the length to the message. This should work out to generate the ! //final manipulation round. ! ESRG_SHA512_Sha512StateStructAddData(state, length_buf, 16); ! ! //Form a string from the hash vector. ! ESRG_SHA512_CopyWordsToStringBuffer(state, result->sha512_chars); ! ! ! //Destroy the state, which may contain sensitive information. ! //This idea came from Rivest's sample code. ! memset(state, 0, sizeof(struct ESRG_SHA512_Sha512StateStruct)); } *************** *** 305,308 **** --- 559,565 ---- /****************************************************************************** ** $Log$ + ** Revision 1.3 2009/11/28 18:17:03 dtashley + ** Development edits. + ** ** Revision 1.2 2009/11/28 06:56:28 dtashley ** Edits. *************** *** 310,314 **** ** Revision 1.1 2009/11/28 00:09:15 dtashley ** Initial checkin. - ** ******************************************************************************* ** End of ESRG_SHA512.C. */ --- 567,570 ---- |