From ba20cc91641edc026e753121a8a989c5e70e5966 Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 25 Jun 2014 10:47:59 +0000 Subject: [PATCH] git-svn-id: svn://10.65.10.50/branches/R_10_00@22967 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- fd/MD5Checksum.cpp | 540 +++++++++++++++++++++++++++++++++++ fd/MD5Checksum.h | 338 ++++++++++++++++++++++ fd/{logo.png => fd0logo.png} | Bin 3 files changed, 878 insertions(+) create mode 100644 fd/MD5Checksum.cpp create mode 100644 fd/MD5Checksum.h rename fd/{logo.png => fd0logo.png} (100%) diff --git a/fd/MD5Checksum.cpp b/fd/MD5Checksum.cpp new file mode 100644 index 000000000..c3862ced5 --- /dev/null +++ b/fd/MD5Checksum.cpp @@ -0,0 +1,540 @@ +/***************************************************************************************** + +*** MD5Checksum.cpp: implementation of the MD5Checksum class. + +*** Developed by Langfine Ltd. +*** Released to the public domain 12/Nov/2001. +*** Please visit our website www.langfine.com + +*** Any modifications must be clearly commented to distinguish them from Langfine's +*** original source code. Please advise Langfine of useful modifications so that we +*** can make them generally available. + +*****************************************************************************************/ + + +/**************************************************************************************** +This software is derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. +Incorporation of this statement is a condition of use; please see the RSA +Data Security Inc copyright notice below:- + +Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*****************************************************************************************/ + +/**************************************************************************************** +This implementation of the RSA MD5 Algorithm was written by Langfine Ltd +(www.langfine.com). + +Langfine Ltd makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +In addition to the above, Langfine make no warrant or assurances regarding the +accuracy of this implementation of the MD5 checksum algorithm nor any assurances regarding +its suitability for any purposes. + +This implementation may be used freely provided that Langfine is credited +in a copyright or similar notices (eg, RSA MD5 Algorithm implemented by Langfine +Ltd.) and provided that the RSA Data Security notices are complied with. +*/ + + +#include "wxinc.h" +#include "wx/filename.h" + +#include "MD5Checksum.h" +#include "MD5ChecksumDefines.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GetMD5 +DETAILS: static, public +DESCRIPTION: Gets the MD5 checksum for a specified file +RETURNS: wxString : the hexadecimal MD5 checksum for the specified file +ARGUMENTS: wxString& strFilePath : the full pathname of the specified file +NOTES: Provides an interface to the wxMD5Checksum class. 'strFilePath' name should + hold the full pathname of the file, eg C:\My Documents\Arcticle.txt. + NB. If any problems occur with opening or reading this file, a CFileException + will be thrown; callers of this function should be ready to catch this + exception. +*****************************************************************************************/ +wxString wxMD5Checksum::GetMD5(const wxString& strFilePath) +{ + if(!wxFileName::FileExists(strFilePath)) + return wxEmptyString; + + //open the file as a binary file in readonly mode, denying write access + wxFile File(strFilePath, wxFile::read); + //the file has been successfully opened, so now get and return its checksum + return GetMD5(File); +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GetMD5 +DETAILS: static, public +DESCRIPTION: Gets the MD5 checksum for a specified file +RETURNS: wxString : the hexadecimal MD5 checksum for the specified file +ARGUMENTS: wxFile& File : the specified file +NOTES: Provides an interface to the wxMD5Checksum class. 'File' should be open in + binary readonly mode before calling this function. + NB. Callers of this function should be ready to catch any CFileException + thrown by the wxFile functions +*****************************************************************************************/ +wxString wxMD5Checksum::GetMD5(wxFile& File) +{ + wxMD5Checksum MD5Checksum; //checksum object + int nLength = 0; //number of bytes read from the file + const int nBufferSize = 1024; //checksum the file in blocks of 1024 bytes + unsigned char Buffer[nBufferSize]; //buffer for data read from the file + + //checksum the file in blocks of 1024 bytes + while ((nLength = File.Read( Buffer, nBufferSize )) > 0 ) + { + MD5Checksum.Update( Buffer, nLength ); + } + + //finalise the checksum and return it + return MD5Checksum.Final(); + +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GetMD5 +DETAILS: static, public +DESCRIPTION: Gets the MD5 checksum for data in a unsigned char array +RETURNS: wxString : the hexadecimal MD5 checksum for the specified data +ARGUMENTS: unsigned char* pBuf : pointer to the unsigned char array + unsigned int nLength : number of BYTEs of data to be checksumed +NOTES: Provides an interface to the wxMD5Checksum class. Any data that can + be cast to a unsigned char array of known length can be checksummed by this + function. Typically, wxString and char arrays will be checksumed, + although this function can be used to check the integrity of any unsigned char array. + A buffer of zero length can be checksummed; all buffers of zero length + will return the same checksum. +*****************************************************************************************/ +wxString wxMD5Checksum::GetMD5(unsigned char* pBuf, unsigned int nLength) +{ + //calculate and return the checksum + wxMD5Checksum MD5Checksum; + MD5Checksum.Update( pBuf, nLength ); + return MD5Checksum.Final(); +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::RotateLeft +DETAILS: private +DESCRIPTION: Rotates the bits in a 32 bit unsigned long left by a specified amount +RETURNS: The rotated unsigned long +ARGUMENTS: unsigned long x : the value to be rotated + int n : the number of bits to rotate by +*****************************************************************************************/ +unsigned long wxMD5Checksum::RotateLeft(unsigned long x, int n) +{ + //check that unsigned long is 4 bytes long - true in Visual C++ 6 and 32 bit Windows + wxASSERT( sizeof(x) == 4 ); + + //rotate and return x + return (x << n) | (x >> (32-n)); +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::FF +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::FF( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long F = (B & C) | (~B & D); + A += F + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GG +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::GG( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long G = (B & D) | (C & ~D); + A += G + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::HH +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::HH( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long H = (B ^ C ^ D); + A += H + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::II +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::II( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long I = (C ^ (B | ~D)); + A += I + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::ByteToDWord +DETAILS: private +DESCRIPTION: Transfers the data in an 8 bit array to a 32 bit array +RETURNS: void +ARGUMENTS: unsigned long* Output : the 32 bit (unsigned long) destination array + unsigned char* Input : the 8 bit (unsigned char) source array + unsigned int nLength : the number of 8 bit data items in the source array +NOTES: Four BYTES from the input array are transferred to each unsigned long entry + of the output array. The first unsigned char is transferred to the bits (0-7) + of the output unsigned long, the second unsigned char to bits 8-15 etc. + The algorithm assumes that the input array is a multiple of 4 bytes long + so that there is a perfect fit into the array of 32 bit words. +*****************************************************************************************/ +void wxMD5Checksum::ByteToDWord(unsigned long* Output, unsigned char* Input, unsigned int nLength) +{ + //entry invariants + wxASSERT( nLength % 4 == 0 ); + + //initialisations + unsigned int i=0; //index to Output array + unsigned int j=0; //index to Input array + + //transfer the data by shifting and copying + for ( ; j < nLength; i++, j += 4) + { + Output[i] = (unsigned long)Input[j] | + (unsigned long)Input[j+1] << 8 | + (unsigned long)Input[j+2] << 16 | + (unsigned long)Input[j+3] << 24; + } +} + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::Transform +DETAILS: protected +DESCRIPTION: MD5 basic transformation algorithm; transforms 'm_lMD5' +RETURNS: void +ARGUMENTS: unsigned char Block[64] +NOTES: An MD5 checksum is calculated by four rounds of 'Transformation'. + The MD5 checksum currently held in m_lMD5 is merged by the + transformation process with data passed in 'Block'. +*****************************************************************************************/ +void wxMD5Checksum::Transform(unsigned char Block[64]) +{ + //initialise local data with current checksum + unsigned long a = m_lMD5[0]; + unsigned long b = m_lMD5[1]; + unsigned long c = m_lMD5[2]; + unsigned long d = m_lMD5[3]; + + //copy BYTES from input 'Block' to an array of ULONGS 'X' + unsigned long X[16]; + ByteToDWord( X, Block, 64 ); + + //Perform Round 1 of the transformation + FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01); + FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02); + FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03); + FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04); + FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05); + FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06); + FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07); + FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08); + FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09); + FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10); + FF (c, d, a, b, X[10], MD5_S13, MD5_T11); + FF (b, c, d, a, X[11], MD5_S14, MD5_T12); + FF (a, b, c, d, X[12], MD5_S11, MD5_T13); + FF (d, a, b, c, X[13], MD5_S12, MD5_T14); + FF (c, d, a, b, X[14], MD5_S13, MD5_T15); + FF (b, c, d, a, X[15], MD5_S14, MD5_T16); + + //Perform Round 2 of the transformation + GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17); + GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18); + GG (c, d, a, b, X[11], MD5_S23, MD5_T19); + GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20); + GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21); + GG (d, a, b, c, X[10], MD5_S22, MD5_T22); + GG (c, d, a, b, X[15], MD5_S23, MD5_T23); + GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24); + GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25); + GG (d, a, b, c, X[14], MD5_S22, MD5_T26); + GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27); + GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28); + GG (a, b, c, d, X[13], MD5_S21, MD5_T29); + GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30); + GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31); + GG (b, c, d, a, X[12], MD5_S24, MD5_T32); + + //Perform Round 3 of the transformation + HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); + HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34); + HH (c, d, a, b, X[11], MD5_S33, MD5_T35); + HH (b, c, d, a, X[14], MD5_S34, MD5_T36); + HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37); + HH (d, a, b, c, X[ 4], MD5_S32, MD5_T38); + HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39); + HH (b, c, d, a, X[10], MD5_S34, MD5_T40); + HH (a, b, c, d, X[13], MD5_S31, MD5_T41); + HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42); + HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43); + HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44); + HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45); + HH (d, a, b, c, X[12], MD5_S32, MD5_T46); + HH (c, d, a, b, X[15], MD5_S33, MD5_T47); + HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48); + + //Perform Round 4 of the transformation + II (a, b, c, d, X[ 0], MD5_S41, MD5_T49); + II (d, a, b, c, X[ 7], MD5_S42, MD5_T50); + II (c, d, a, b, X[14], MD5_S43, MD5_T51); + II (b, c, d, a, X[ 5], MD5_S44, MD5_T52); + II (a, b, c, d, X[12], MD5_S41, MD5_T53); + II (d, a, b, c, X[ 3], MD5_S42, MD5_T54); + II (c, d, a, b, X[10], MD5_S43, MD5_T55); + II (b, c, d, a, X[ 1], MD5_S44, MD5_T56); + II (a, b, c, d, X[ 8], MD5_S41, MD5_T57); + II (d, a, b, c, X[15], MD5_S42, MD5_T58); + II (c, d, a, b, X[ 6], MD5_S43, MD5_T59); + II (b, c, d, a, X[13], MD5_S44, MD5_T60); + II (a, b, c, d, X[ 4], MD5_S41, MD5_T61); + II (d, a, b, c, X[11], MD5_S42, MD5_T62); + II (c, d, a, b, X[ 2], MD5_S43, MD5_T63); + II (b, c, d, a, X[ 9], MD5_S44, MD5_T64); + + //add the transformed values to the current checksum + m_lMD5[0] += a; + m_lMD5[1] += b; + m_lMD5[2] += c; + m_lMD5[3] += d; +} + + +/***************************************************************************************** +CONSTRUCTOR: wxMD5Checksum +DESCRIPTION: Initialises member data +ARGUMENTS: None +NOTES: None +*****************************************************************************************/ +wxMD5Checksum::wxMD5Checksum() +{ + // zero members + memset( m_lpszBuffer, 0, 64 ); + m_nCount[0] = m_nCount[1] = 0; + + // Load magic state initialization constants + m_lMD5[0] = MD5_INIT_STATE_0; + m_lMD5[1] = MD5_INIT_STATE_1; + m_lMD5[2] = MD5_INIT_STATE_2; + m_lMD5[3] = MD5_INIT_STATE_3; +} + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::DWordToByte +DETAILS: private +DESCRIPTION: Transfers the data in an 32 bit array to a 8 bit array +RETURNS: void +ARGUMENTS: unsigned char* Output : the 8 bit destination array + unsigned long* Input : the 32 bit source array + unsigned int nLength : the number of 8 bit data items in the source array +NOTES: One unsigned long from the input array is transferred into four BYTES + in the output array. The first (0-7) bits of the first unsigned long are + transferred to the first output unsigned char, bits bits 8-15 are transferred from + the second unsigned char etc. + + The algorithm assumes that the output array is a multiple of 4 bytes long + so that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs. +*****************************************************************************************/ +void wxMD5Checksum::DWordToByte(unsigned char* Output, unsigned long* Input, unsigned int nLength ) +{ + //entry invariants + wxASSERT( nLength % 4 == 0 ); + + //transfer the data by shifting and copying + unsigned int i = 0; + unsigned int j = 0; + for ( ; j < nLength; i++, j += 4) + { + Output[j] = (UCHAR)(Input[i] & 0xff); + Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff); + Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff); + Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff); + } +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::Final +DETAILS: protected +DESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checksum calculation. +RETURNS: wxString : the final hexadecimal MD5 checksum result +ARGUMENTS: None +NOTES: Performs the final MD5 checksum calculation ('Update' does most of the work, + this function just finishes the calculation.) +*****************************************************************************************/ +wxString wxMD5Checksum::Final() +{ + //Save number of bits + unsigned char Bits[8]; + DWordToByte( Bits, m_nCount, 8 ); + + //Pad out to 56 mod 64. + unsigned int nIndex = (unsigned int)((m_nCount[0] >> 3) & 0x3f); + unsigned int nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); + Update( PADDING, nPadLen ); + + //Append length (before padding) + Update( Bits, 8 ); + + //Store final state in 'lpszMD5' + const int nMD5Size = 16; + unsigned char lpszMD5[ nMD5Size ]; + DWordToByte( lpszMD5, m_lMD5, nMD5Size ); + + //Convert the hexadecimal checksum to a wxString + wxString strMD5; + for ( int i=0; i < nMD5Size; i++) + { + wxString Str; + if (lpszMD5[i] == 0) { + Str = wxT("00"); + } + else if (lpszMD5[i] <= 15) { + Str.Printf(wxT("0%x"),lpszMD5[i]); + } + else { + Str.Printf(wxT("%x"),lpszMD5[i]); + } + + wxASSERT( Str.Length() == 2 ); + strMD5 += Str; + } + wxASSERT( strMD5.Length() == 32 ); + return strMD5; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::Update +DETAILS: protected +DESCRIPTION: Implementation of main MD5 checksum algorithm +RETURNS: void +ARGUMENTS: unsigned char* Input : input block + unsigned int nInputLen : length of input block +NOTES: Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input' +*****************************************************************************************/ +void wxMD5Checksum::Update( unsigned char* Input, unsigned long nInputLen ) +{ + //Compute number of bytes mod 64 + unsigned int nIndex = (unsigned int)((m_nCount[0] >> 3) & 0x3F); + + //Update number of bits + if ( ( m_nCount[0] += nInputLen << 3 ) < ( nInputLen << 3) ) + { + m_nCount[1]++; + } + m_nCount[1] += (nInputLen >> 29); + + //Transform as many times as possible. + unsigned int i=0; + unsigned int nPartLen = 64 - nIndex; + if (nInputLen >= nPartLen) + { + memcpy( &m_lpszBuffer[nIndex], Input, nPartLen ); + Transform( m_lpszBuffer ); + for (i = nPartLen; i + 63 < nInputLen; i += 64) + { + Transform( &Input[i] ); + } + nIndex = 0; + } + else + { + i = 0; + } + + // Buffer remaining input + memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i); +} + + diff --git a/fd/MD5Checksum.h b/fd/MD5Checksum.h new file mode 100644 index 000000000..cec919759 --- /dev/null +++ b/fd/MD5Checksum.h @@ -0,0 +1,338 @@ +/***************************************************************************************** + +*** MD5Checksum.h: interface for the MD5Checksum class. + +*** Developed by Langfine Ltd. +*** Released to the public domain 12/Nov/2001. +*** Please visit our website www.langfine.com + +*** Any modifications must be clearly commented to distinguish them from Langfine's +*** original source code. Please advise Langfine of useful modifications so that we +*** can make them generally available. + +*****************************************************************************************/ + + +#ifndef __MD5CHECKSUM_H__ +#define __MD5CHECKSUM_H__ + +#include +/**************************************************************************************** +This software is derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. +Incorporation of this statement is a condition of use; please see the RSA +Data Security Inc copyright notice below:- + +Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*****************************************************************************************/ + +/**************************************************************************************** +This implementation of the RSA MD5 Algorithm was written by Langfine Ltd. + +Langfine Ltd makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +In addition to the above, Langfine make no warrant or assurances regarding the +accuracy of this implementation of the MD5 checksum algorithm nor any assurances regarding +its suitability for any purposes. + +This implementation may be used freely provided that Langfine is credited +in a copyright or similar notices (eg, RSA MD5 Algorithm implemented by Langfine +Ltd.) and provided that the RSA Data Security notices are complied with. + +Langfine may be contacted at mail@langfine.com +*/ + +/***************************************************************************************** +CLASS: wxMD5Checksum +DESCRIPTION: Implements the "RSA Data Security, Inc. MD5 Message-Digest Algorithm". +NOTES: Calculates the RSA MD5 checksum for a file or congiguous array of data. + +Below are extracts from a memo on The MD5 Message-Digest Algorithm by R. Rivest of MIT +Laboratory for Computer Science and RSA Data Security, Inc., April 1992. + + 1. Executive Summary + This document describes the MD5 message-digest algorithm. The + algorithm takes as input a message of arbitrary length and produces + as output a 128-bit "fingerprint" or "message digest" of the input. + It is conjectured that it is computationally infeasible to produce + two messages having the same message digest, or to produce any + message having a given prespecified target message digest. The MD5 + algorithm is intended for digital signature applications, where a + large file must be "compressed" in a secure manner before being + encrypted with a private (secret) key under a public-key cryptosystem + such as RSA. + + The MD5 algorithm is designed to be quite fast on 32-bit machines. In + addition, the MD5 algorithm does not require any large substitution + tables; the algorithm can be coded quite compactly. + The MD5 algorithm is an extension of the MD4 message-digest algorithm + 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in + design. MD5 was designed because it was felt that MD4 was perhaps + being adopted for use more quickly than justified by the existing + critical review; because MD4 was designed to be exceptionally fast, + it is "at the edge" in terms of risking successful cryptanalytic + attack. MD5 backs off a bit, giving up a little in speed for a much + greater likelihood of ultimate security. It incorporates some + suggestions made by various reviewers, and contains additional + optimizations. The MD5 algorithm is being placed in the public domain + for review and possible adoption as a standard. + + + 2. Terminology and Notation + In this document a "word" is a 32-bit quantity and a "byte" is an + eight-bit quantity. A sequence of bits can be interpreted in a + natural manner as a sequence of bytes, where each consecutive group + of eight bits is interpreted as a byte with the high-order (most + significant) bit of each byte listed first. Similarly, a sequence of + bytes can be interpreted as a sequence of 32-bit words, where each + consecutive group of four bytes is interpreted as a word with the + low-order (least significant) byte given first. + Let x_i denote "x sub i". If the subscript is an expression, we + surround it in braces, as in x_{i+1}. Similarly, we use ^ for + superscripts (exponentiation), so that x^i denotes x to the i-th power. + Let the symbol "+" denote addition of words (i.e., modulo-2^32 + addition). Let X <<< s denote the 32-bit value obtained by circularly + shifting (rotating) X left by s bit positions. Let not(X) denote the + bit-wise complement of X, and let X v Y denote the bit-wise OR of X + and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY + denote the bit-wise AND of X and Y. + + + 3. MD5 Algorithm Description + We begin by supposing that we have a b-bit message as input, and that + we wish to find its message digest. Here b is an arbitrary + nonnegative integer; b may be zero, it need not be a multiple of + eight, and it may be arbitrarily large. We imagine the bits of the + message written down as follows: m_0 m_1 ... m_{b-1} + The following five steps are performed to compute the message digest + of the message. + + 3.1 Step 1. Append Padding Bits + The message is "padded" (extended) so that its length (in bits) is + congruent to 448, modulo 512. That is, the message is extended so + that it is just 64 bits shy of being a multiple of 512 bits long. + Padding is always performed, even if the length of the message is + already congruent to 448, modulo 512. + Padding is performed as follows: a single "1" bit is appended to the + message, and then "0" bits are appended so that the length in bits of + the padded message becomes congruent to 448, modulo 512. In all, at + least one bit and at most 512 bits are appended. + + 3.2 Step 2. Append Length + A 64-bit representation of b (the length of the message before the + padding bits were added) is appended to the result of the previous + step. In the unlikely event that b is greater than 2^64, then only + the low-order 64 bits of b are used. (These bits are appended as two + 32-bit words and appended low-order word first in accordance with the + previous conventions.) + At this point the resulting message (after padding with bits and with + b) has a length that is an exact multiple of 512 bits. Equivalently, + this message has a length that is an exact multiple of 16 (32-bit) + words. Let M[0 ... N-1] denote the words of the resulting message, + where N is a multiple of 16. + + 3.3 Step 3. Initialize MD Buffer + A four-word buffer (A,B,C,D) is used to compute the message digest. + Here each of A, B, C, D is a 32-bit register. These registers are + initialized to the following values in hexadecimal, low-order bytes first): + word A: 01 23 45 67 word B: 89 ab cd ef + word C: fe dc ba 98 word D: 76 54 32 10 + + 3.4 Step 4. Process Message in 16-Word Blocks + We first define four auxiliary functions that each take as input + three 32-bit words and produce as output one 32-bit word. + F(X,Y,Z) = XY v not(X) Z G(X,Y,Z) = XZ v Y not(Z) + H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X v not(Z)) + In each bit position F acts as a conditional: if X then Y else Z. + The function F could have been defined using + instead of v since XY + and not(X)Z will never have 1's in the same bit position.) It is + interesting to note that if the bits of X, Y, and Z are independent + and unbiased, the each bit of F(X,Y,Z) will be independent and unbiased. + The functions G, H, and I are similar to the function F, in that they + act in "bitwise parallel" to produce their output from the bits of X, + Y, and Z, in such a manner that if the corresponding bits of X, Y, + and Z are independent and unbiased, then each bit of G(X,Y,Z), + H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that + the function H is the bit-wise "xor" or "parity" function of its inputs. + This step uses a 64-element table T[1 ... 64] constructed from the + sine function. Let T[i] denote the i-th element of the table, which + is equal to the integer part of 4294967296 times abs(sin(i)), where i + is in radians. The elements of the table are given in the appendix. + Do the following: + + //Process each 16-word block. + For i = 0 to N/16-1 do // Copy block i into X. + For j = 0 to 15 do + Set X[j] to M[i*16+j]. + end //of loop on j + + // Save A as AA, B as BB, C as CC, and D as DD. + AA = A BB = B + CC = C DD = D + + // Round 1. + // Let [abcd k s i] denote the operation + // a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] + [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8] + [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12] + [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16] + + // Round 2. + // Let [abcd k s i] denote the operation + // a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20] + [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24] + [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28] + [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32] + + // Round 3. + // Let [abcd k s t] denote the operation + // a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36] + [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40] + [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44] + [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48] + + // Round 4. + // Let [abcd k s t] denote the operation + // a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52] + [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56] + [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] + [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] + + // Then perform the following additions. (That is increment each + // of the four registers by the value it had before this block + // was started.) + A = A + AA B = B + BB C = C + CC D = D + DD + + end // of loop on i + + 3.5 Step 5. Output + The message digest produced as output is A, B, C, D. That is, we + begin with the low-order byte of A, and end with the high-order byte of D. + This completes the description of MD5. + + Summary + The MD5 message-digest algorithm is simple to implement, and provides + a "fingerprint" or message digest of a message of arbitrary length. + It is conjectured that the difficulty of coming up with two messages + having the same message digest is on the order of 2^64 operations, + and that the difficulty of coming up with any message having a given + message digest is on the order of 2^128 operations. The MD5 algorithm + has been carefully scrutinized for weaknesses. It is, however, a + relatively new algorithm and further security analysis is of course + justified, as is the case with any new proposal of this sort. + + + 5. Differences Between MD4 and MD5 + The following are the differences between MD4 and MD5: + 1. A fourth round has been added. + 2. Each step now has a unique additive constant. + 3. The function g in round 2 was changed from (XY v XZ v YZ) to + (XZ v Y not(Z)) to make g less symmetric. + 4. Each step now adds in the result of the previous step. This + promotes a faster "avalanche effect". + 5. The order in which input words are accessed in rounds 2 and + 3 is changed, to make these patterns less like each other. + 6. The shift amounts in each round have been approximately + optimized, to yield a faster "avalanche effect." The shifts in + different rounds are distinct. + + References + [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and + RSA Data Security, Inc., April 1992. + [2] Rivest, R., "The MD4 message digest algorithm", in A.J. Menezes + and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90 + Proceedings, pages 303-311, Springer-Verlag, 1991. + [3] CCITT Recommendation X.509 (1988), "The Directory - + Authentication Framework."APPENDIX A - Reference Implementation + + + The level of security discussed in this memo is considered to be + sufficient for implementing very high security hybrid digital- + signature schemes based on MD5 and a public-key cryptosystem. + Author's Address + Ronald L. Rivest Massachusetts Institute of Technology + Laboratory for Computer Science NE43-324 545 Technology Square + Cambridge, MA 02139-1986 Phone: (617) 253-5880 + EMail: rivest@theory.lcs.mit.edu + + +*****************************************************************************************/ +class wxMD5Checksum +{ +public: + // interface functions for the RSA MD5 calculation + static wxString GetMD5(unsigned char* pBuf, unsigned int nLength); + static wxString GetMD5(wxFile& File); + static wxString GetMD5(const wxString& strFilePath); + +protected: + // constructor/destructor + wxMD5Checksum(); + virtual ~wxMD5Checksum() {}; + + // RSA MD5 implementation + void Transform(unsigned char Block[64]); + void Update(unsigned char* Input, unsigned long nInputLen); + wxString Final(); + inline unsigned long RotateLeft(unsigned long x, int n); + inline void FF( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + inline void GG( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + inline void HH( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + inline void II( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + + // utility functions + inline void DWordToByte(unsigned char* Output, unsigned long* Input, unsigned int nLength); + inline void ByteToDWord(unsigned long* Output, unsigned char* Input, unsigned int nLength); + +private: + unsigned char m_lpszBuffer[64]; // input buffer + unsigned long m_nCount[2]; // number of bits, modulo 2^64 (lsb first) + unsigned long m_lMD5[4]; // MD5 checksum +}; + +#endif + + + + + + + + diff --git a/fd/logo.png b/fd/fd0logo.png similarity index 100% rename from fd/logo.png rename to fd/fd0logo.png