[Project64] MD5.cpp auto code clean up

This commit is contained in:
zilmar 2015-12-10 17:23:03 +11:00
parent 17b24f299f
commit 22fc35d49c
2 changed files with 306 additions and 359 deletions

View File

@ -1,14 +1,14 @@
// MD5.CC - source code for the C++/object oriented translation and // MD5.CC - source code for the C++/object oriented translation and
// modification of MD5. // modification of MD5.
// Translation and modification (c) 1995 by Mordechai T. Abzug // Translation and modification (c) 1995 by Mordechai T. Abzug
// This translation/ modification is provided "as is," without express or // This translation/ modification is provided "as is," without express or
// implied warranty of any kind. // implied warranty of any kind.
// The translator/ modifier does not claim (1) that MD5 will do what you think // The translator/ modifier does not claim (1) that MD5 will do what you think
// it does; (2) that this translation/ modification is accurate; or (3) that // it does; (2) that this translation/ modification is accurate; or (3) that
// this software is "merchantible." (Language for this disclaimer partially // this software is "merchantible." (Language for this disclaimer partially
// copied from the disclaimer below). // copied from the disclaimer below).
/* based on: /* based on:
@ -16,29 +16,28 @@
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
MDDRIVER.C - test driver for MD2, MD4 and MD5 MDDRIVER.C - test driver for MD2, MD4 and MD5
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved. rights reserved.
License to copy and use this software is granted provided that it License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software Algorithm" in all material mentioning or referencing this software
or this function. or this function.
License is also granted to make and use derivative works provided License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work. mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is" software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind. without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this These notices must be retained in any copies of any part of this
documentation and/or software. documentation and/or software.
*/ */
#include "stdafx.h" #include "stdafx.h"
#include <TChar.H> #include <TChar.H>
@ -46,237 +45,213 @@ documentation and/or software.
// MD5 simple initialization method // MD5 simple initialization method
MD5::MD5(){ MD5::MD5(){
init();
init();
} }
MD5::~MD5() MD5::~MD5()
{ {
} }
// MD5 block update operation. Continues an MD5 message-digest // MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block, and updating the // operation, processing another message block, and updating the
// context. // context.
void MD5::update (const uint1 *input, uint4 input_length) { void MD5::update(const uint1 *input, uint4 input_length) {
uint4 input_index, buffer_index;
uint4 buffer_space; // how much space is left in buffer
uint4 input_index, buffer_index; if (finalized){ // so we can't update!
uint4 buffer_space; // how much space is left in buffer WriteTrace(TraceError, _T("MD5::update: Can't update a finalized digest!"));
return;
}
if (finalized){ // so we can't update! // Compute number of bytes mod 64
WriteTrace(TraceError, _T("MD5::update: Can't update a finalized digest!")); buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
return;
}
// Compute number of bytes mod 64 // Update number of bits
buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); if ((count[0] += ((uint4)input_length << 3)) < ((uint4)input_length << 3))
count[1]++;
// Update number of bits count[1] += ((uint4)input_length >> 29);
if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
count[1]++;
count[1] += ((uint4)input_length >> 29); buffer_space = 64 - buffer_index; // how much space is left in buffer
// Transform as many times as possible.
if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
// fill the rest of the buffer and transform
memcpy(buffer + buffer_index, (unsigned char *)input, buffer_space);
transform(buffer);
buffer_space = 64 - buffer_index; // how much space is left in buffer // now, transform each 64-byte piece of the input, bypassing the buffer
for (input_index = buffer_space; input_index + 63 < input_length;
input_index += 64)
transform((unsigned char *)(input + input_index));
// Transform as many times as possible. buffer_index = 0; // so we can buffer remaining
if (input_length >= buffer_space) { // ie. we have enough to fill the buffer }
// fill the rest of the buffer and transform else
memcpy (buffer + buffer_index, (unsigned char *)input, buffer_space); input_index = 0; // so we can buffer the whole input
transform (buffer);
// now, transform each 64-byte piece of the input, bypassing the buffer // and here we do the buffering:
for (input_index = buffer_space; input_index + 63 < input_length; memcpy(buffer + buffer_index, (unsigned char *)(input + input_index), input_length - input_index);
input_index += 64)
transform ((unsigned char *)(input+input_index));
buffer_index = 0; // so we can buffer remaining
}
else
input_index=0; // so we can buffer the whole input
// and here we do the buffering:
memcpy(buffer+buffer_index, (unsigned char *)(input+input_index), input_length-input_index);
} }
// MD5 update for files. // MD5 update for files.
// Like above, except that it works on files (and uses above as a primitive.) // Like above, except that it works on files (and uses above as a primitive.)
void MD5::update(FILE *file){ void MD5::update(FILE *file){
unsigned char buffer[1024];
int len;
unsigned char buffer[1024]; do
int len; {
len = (int)fread(buffer, 1, 1024, file);
do if (len)
{ {
len = (int)fread(buffer, 1, 1024, file); update(buffer, len);
if (len) }
{ } while (len);
update(buffer, len);
}
} while (len);
fclose (file);
fclose(file);
} }
// MD5 finalization. Ends an MD5 message-digest operation, writing the // MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context. // the message digest and zeroizing the context.
void MD5::finalize(){
void MD5::finalize (){ unsigned char bits[8];
unsigned int index, padLen;
unsigned char bits[8]; static uint1 PADDING[64] = {
unsigned int index, padLen; 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
static uint1 PADDING[64]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
if (finalized){ if (finalized){
WriteTrace(TraceError, _T("MD5::finalize: Already finalized this digest!")); WriteTrace(TraceError, _T("MD5::finalize: Already finalized this digest!"));
return; return;
} }
// Save number of bits // Save number of bits
encode (bits, count, 8); encode(bits, count, 8);
// Pad out to 56 mod 64. // Pad out to 56 mod 64.
index = (uint4) ((count[0] >> 3) & 0x3f); index = (uint4)((count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index); padLen = (index < 56) ? (56 - index) : (120 - index);
update (PADDING, padLen); update(PADDING, padLen);
// Append length (before padding) // Append length (before padding)
update (bits, 8); update(bits, 8);
// Store state in digest // Store state in digest
encode (digest, state, 16); encode(digest, state, 16);
// Zeroize sensitive information // Zeroize sensitive information
memset (buffer, 0, sizeof(*buffer)); memset(buffer, 0, sizeof(*buffer));
finalized=1;
finalized = 1;
} }
MD5::MD5(CPath File){ MD5::MD5(CPath File){
init(); // must be called be all constructors
init(); // must be called be all constructors if (File.Exists())
if (File.Exists()) {
{ FILE * fp = fopen((LPCTSTR)File, _T("rb"));
FILE * fp = fopen((LPCTSTR)File,_T("rb")); if (fp)
if (fp) {
{ update(fp);
update(fp); }
} }
} finalize();
finalize ();
} }
MD5::MD5(FILE *file){ MD5::MD5(FILE *file){
init(); // must be called be all constructors
init(); // must be called be all constructors update(file);
update(file); finalize();
finalize ();
} }
MD5::MD5(const unsigned char *input, unsigned int input_length) MD5::MD5(const unsigned char *input, unsigned int input_length)
{ {
init(); // must called by all constructors init(); // must called by all constructors
update (input,input_length); update(input, input_length);
finalize(); finalize();
} }
MD5::MD5(const stdstr & string) MD5::MD5(const stdstr & string)
{ {
init(); // must called by all constructors init(); // must called by all constructors
update ((const unsigned char *)string.c_str(),string.length()); update((const unsigned char *)string.c_str(), string.length());
finalize(); finalize();
} }
const unsigned char *MD5::raw_digest() const unsigned char *MD5::raw_digest()
{ {
if (!finalized){ if (!finalized){
WriteTrace(TraceError, _T("MD5::raw_digest: Can't get digest if you haven't finalized the digest!")); WriteTrace(TraceError, _T("MD5::raw_digest: Can't get digest if you haven't finalized the digest!"));
return ( (unsigned char*) ""); return ((unsigned char*) "");
} }
return digest; return digest;
} }
void MD5::get_digest(MD5Digest& extdigest) void MD5::get_digest(MD5Digest& extdigest)
{ {
if (!finalized) if (!finalized)
{ {
WriteTrace(TraceError,_T("MD5::get_digest: Can't get digest if you haven't finalized the digest!")); WriteTrace(TraceError, _T("MD5::get_digest: Can't get digest if you haven't finalized the digest!"));
memset(extdigest.digest, 0, sizeof(extdigest.digest)); memset(extdigest.digest, 0, sizeof(extdigest.digest));
return; return;
} }
memcpy(extdigest.digest, digest, 16); memcpy(extdigest.digest, digest, 16);
} }
const char *MD5::hex_digest() const char *MD5::hex_digest()
{ {
if (m_hex_digest.length()) if (m_hex_digest.length())
{ {
return m_hex_digest.c_str(); return m_hex_digest.c_str();
} }
if (!finalized) if (!finalized)
{ {
WriteTrace(TraceError,_T("MD5::hex_digest: Can't get digest if you haven't finalized the digest!")); WriteTrace(TraceError, _T("MD5::hex_digest: Can't get digest if you haven't finalized the digest!"));
return ""; return "";
} }
char c[33]; char c[33];
memset((unsigned char *)c, 0, 33); memset((unsigned char *)c, 0, 33);
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
sprintf(c + i * 2, "%02X", digest[i]); sprintf(c + i * 2, "%02X", digest[i]);
} }
c[32] = '\0'; c[32] = '\0';
m_hex_digest = c; m_hex_digest = c;
return m_hex_digest.c_str(); return m_hex_digest.c_str();
} }
// PRIVATE METHODS: // PRIVATE METHODS:
void MD5::init(){ void MD5::init(){
finalized=0; // we just started! finalized = 0; // we just started!
// Nothing counted, so count=0 // Nothing counted, so count=0
count[0] = 0; count[0] = 0;
count[1] = 0; count[1] = 0;
// Load magic initialization constants. // Load magic initialization constants.
state[0] = 0x67452301; state[0] = 0x67452301;
state[1] = 0xefcdab89; state[1] = 0xefcdab89;
state[2] = 0x98badcfe; state[2] = 0x98badcfe;
state[3] = 0x10325476; state[3] = 0x10325476;
::memset(digest, 0, sizeof(digest)); ::memset(digest, 0, sizeof(digest));
::memset(buffer, 0, sizeof(buffer)); ::memset(buffer, 0, sizeof(buffer));
m_hex_digest = NULL; m_hex_digest = NULL;
} }
// Constants for MD5Transform routine. // Constants for MD5Transform routine.
// Although we could use C++ style constants, defines are actually better, // Although we could use C++ style constants, defines are actually better,
// since they let us easily evade scope clashes. // since they let us easily evade scope clashes.
@ -298,209 +273,181 @@ void MD5::init(){
#define S43 15 #define S43 15
#define S44 21 #define S44 21
// MD5 basic transformation. Transforms state based on block. // MD5 basic transformation. Transforms state based on block.
void MD5::transform (uint1 block[64]){ void MD5::transform(uint1 block[64]){
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; decode(x, block, 64);
decode (x, block, 64); //ATLASSERT(!finalized); // not just a user error, since the method is private
//ATLASSERT(!finalized); // not just a user error, since the method is private /* Round 1 */
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 1 */ /* Round 2 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 2 */ /* Round 3 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
/* Round 3 */ /* Round 4 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
/* Round 4 */ state[0] += a;
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ state[1] += b;
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ state[2] += c;
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ state[3] += d;
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
// Zeroize sensitive information.
memset ( (uint1 *) x, 0, sizeof(x));
// Zeroize sensitive information.
memset((uint1 *)x, 0, sizeof(x));
} }
// Encodes input (UINT4) into output (unsigned char). Assumes len is // Encodes input (UINT4) into output (unsigned char). Assumes len is
// a multiple of 4. // a multiple of 4.
void MD5::encode (uint1 *output, uint4 *input, uint4 len) { void MD5::encode(uint1 *output, uint4 *input, uint4 len) {
unsigned int i, j;
unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (uint1)(input[i] & 0xff);
for (i = 0, j = 0; j < len; i++, j += 4) { output[j + 1] = (uint1)((input[i] >> 8) & 0xff);
output[j] = (uint1) (input[i] & 0xff); output[j + 2] = (uint1)((input[i] >> 16) & 0xff);
output[j+1] = (uint1) ((input[i] >> 8) & 0xff); output[j + 3] = (uint1)((input[i] >> 24) & 0xff);
output[j+2] = (uint1) ((input[i] >> 16) & 0xff); }
output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
}
} }
// Decodes input (unsigned char) into output (UINT4). Assumes len is // Decodes input (unsigned char) into output (UINT4). Assumes len is
// a multiple of 4. // a multiple of 4.
void MD5::decode (uint4 *output, uint1 *input, uint4 len){ void MD5::decode(uint4 *output, uint1 *input, uint4 len){
unsigned int i, j;
unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
for (i = 0, j = 0; j < len; i++, j += 4) (((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
} }
// Note: Replace "for loop" with standard memcpy if possible. // Note: Replace "for loop" with standard memcpy if possible.
void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){ void MD5::memcpy(uint1 *output, uint1 *input, uint4 len){
unsigned int i;
unsigned int i; for (i = 0; i < len; i++)
output[i] = input[i];
for (i = 0; i < len; i++)
output[i] = input[i];
} }
// Note: Replace "for loop" with standard memset if possible. // Note: Replace "for loop" with standard memset if possible.
void MD5::memset (uint1 *output, uint1 value, uint4 len){ void MD5::memset(uint1 *output, uint1 value, uint4 len){
unsigned int i;
unsigned int i; for (i = 0; i < len; i++)
output[i] = value;
for (i = 0; i < len; i++)
output[i] = value;
} }
// ROTATE_LEFT rotates x left n bits. // ROTATE_LEFT rotates x left n bits.
inline unsigned int MD5::rotate_left (uint4 x, uint4 n){ inline unsigned int MD5::rotate_left(uint4 x, uint4 n){
return (x << n) | (x >> (32-n)) ; return (x << n) | (x >> (32 - n));
} }
// F, G, H and I are basic MD5 functions. // F, G, H and I are basic MD5 functions.
inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){ inline unsigned int MD5::F(uint4 x, uint4 y, uint4 z){
return (x & y) | (~x & z); return (x & y) | (~x & z);
} }
inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){ inline unsigned int MD5::G(uint4 x, uint4 y, uint4 z){
return (x & z) | (y & ~z); return (x & z) | (y & ~z);
} }
inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){ inline unsigned int MD5::H(uint4 x, uint4 y, uint4 z){
return x ^ y ^ z; return x ^ y ^ z;
} }
inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){ inline unsigned int MD5::I(uint4 x, uint4 y, uint4 z){
return y ^ (x | ~z); return y ^ (x | ~z);
} }
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation. // Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac){
uint4 s, uint4 ac){ a += F(b, c, d) + x + ac;
a += F(b, c, d) + x + ac; a = rotate_left(a, s) + b;
a = rotate_left (a, s) +b;
} }
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){ uint4 s, uint4 ac){
a += G(b, c, d) + x + ac; a += G(b, c, d) + x + ac;
a = rotate_left (a, s) +b; a = rotate_left(a, s) + b;
} }
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){ uint4 s, uint4 ac){
a += H(b, c, d) + x + ac; a += H(b, c, d) + x + ac;
a = rotate_left (a, s) +b; a = rotate_left(a, s) + b;
} }
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){ uint4 s, uint4 ac){
a += I(b, c, d) + x + ac; a += I(b, c, d) + x + ac;
a = rotate_left (a, s) +b; a = rotate_left(a, s) + b;
} }

View File

@ -54,13 +54,13 @@ struct MD5Digest
bool IsClear() bool IsClear()
{ {
int isClear = 0; int isClear = 0;
for (int i=0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
isClear += digest[i]; isClear += digest[i];
} }
return (isClear == 0); return (isClear == 0);
} }
std::string String ( void ) std::string String(void)
{ {
char s[33]; char s[33];
@ -68,15 +68,15 @@ struct MD5Digest
for (int i = 0; i < 16; i++) for (int i = 0; i < 16; i++)
{ {
sprintf(s+i*2, "%02X", digest[i]); sprintf(s + i * 2, "%02X", digest[i]);
} }
s[32]='\0'; s[32] = '\0';
return s; return s;
} }
}; };
struct MD5Digest_less : std::binary_function<MD5Digest, MD5Digest, bool> struct MD5Digest_less : std::binary_function < MD5Digest, MD5Digest, bool >
{ {
bool operator()(const MD5Digest& x, const MD5Digest& y) const bool operator()(const MD5Digest& x, const MD5Digest& y) const
{ {
@ -88,24 +88,24 @@ class MD5
{ {
public: public:
// methods for controlled operation: // methods for controlled operation:
MD5 (); // simple initializer MD5(); // simple initializer
~MD5 (); ~MD5();
void update (const unsigned char *input, unsigned int input_length); void update(const unsigned char *input, unsigned int input_length);
void update (FILE *file); void update(FILE *file);
void finalize (); void finalize();
// constructors for special circumstances. All these constructors finalize // constructors for special circumstances. All these constructors finalize
// the MD5 context. // the MD5 context.
MD5 (CPath File); // digest File, finalize MD5(CPath File); // digest File, finalize
MD5 (const unsigned char *string); // digest string, finalize MD5(const unsigned char *string); // digest string, finalize
MD5 (FILE *file); // digest file, close, finalize MD5(FILE *file); // digest file, close, finalize
MD5 (const unsigned char *input, unsigned int input_length); MD5(const unsigned char *input, unsigned int input_length);
MD5 (const stdstr & string); MD5(const stdstr & string);
// methods to acquire finalized result // methods to acquire finalized result
void get_digest(MD5Digest& extdigest); //Digest into a digest structure void get_digest(MD5Digest& extdigest); //Digest into a digest structure
const unsigned char *raw_digest (); // digest as a 16-byte binary array const unsigned char *raw_digest(); // digest as a 16-byte binary array
const char * hex_digest (); // digest as a 33-byte ascii-hex string const char * hex_digest(); // digest as a 33-byte ascii-hex string
private: private:
@ -123,26 +123,26 @@ private:
stdstr m_hex_digest; stdstr m_hex_digest;
// last, the private methods, mostly static: // last, the private methods, mostly static:
void init (); // called by all constructors void init(); // called by all constructors
void transform (uint1 *buffer); // does the real update work. Note void transform(uint1 *buffer); // does the real update work. Note
// that length is implied to be 64. // that length is implied to be 64.
static void encode (uint1 *dest, uint4 *src, uint4 length); static void encode(uint1 *dest, uint4 *src, uint4 length);
static void decode (uint4 *dest, uint1 *src, uint4 length); static void decode(uint4 *dest, uint1 *src, uint4 length);
static void memcpy (uint1 *dest, uint1 *src, uint4 length); static void memcpy(uint1 *dest, uint1 *src, uint4 length);
static void memset (uint1 *start, uint1 val, uint4 length); static void memset(uint1 *start, uint1 val, uint4 length);
static inline uint4 rotate_left (uint4 x, uint4 n); static inline uint4 rotate_left(uint4 x, uint4 n);
static inline uint4 F (uint4 x, uint4 y, uint4 z); static inline uint4 F(uint4 x, uint4 y, uint4 z);
static inline uint4 G (uint4 x, uint4 y, uint4 z); static inline uint4 G(uint4 x, uint4 y, uint4 z);
static inline uint4 H (uint4 x, uint4 y, uint4 z); static inline uint4 H(uint4 x, uint4 y, uint4 z);
static inline uint4 I (uint4 x, uint4 y, uint4 z); static inline uint4 I(uint4 x, uint4 y, uint4 z);
static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, static inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac); uint4 s, uint4 ac);
static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, static inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac); uint4 s, uint4 ac);
static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, static inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac); uint4 s, uint4 ac);
static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, static inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac); uint4 s, uint4 ac);
}; };