Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

md5.cpp

Go to the documentation of this file.
00001 /* 00002 * MD5 00003 * Written by Julien Couot. 00004 * Original C version written by Ulrich Drepper. 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 */ 00020 00021 /** 00022 * \file md5.cpp 00023 * Compute md5. 00024 */ 00025 00026 //--------------------------------------------------------------------------- 00027 // For compilers that support precompilation, includes "wx.h". 00028 #include <wx/wxprec.h> 00029 00030 #ifdef __BORLANDC__ 00031 #pragma hdrstop 00032 #endif 00033 00034 #ifndef WX_PRECOMP 00035 // Include your minimal set of headers here, or wx.h 00036 #include <wx/wx.h> 00037 #endif 00038 00039 #include "md5.hpp" 00040 00041 #include "compat.hpp" 00042 //--------------------------------------------------------------------------- 00043 00044 /// The C++ standard namespace. 00045 using namespace std; 00046 //--------------------------------------------------------------------------- 00047 00048 00049 // This array contains the bytes used to pad the buffer to the next 00050 // 64-byte boundary. (RFC 1321, 3.1: Step 1) 00051 const wxByte MD5::fillbuf[64] = { 00052 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00053 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00054 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 00055 //--------------------------------------------------------------------------- 00056 00057 00058 /* 00059 * Default constructor. 00060 */ 00061 MD5::MD5() 00062 { 00063 reset(); 00064 } 00065 //--------------------------------------------------------------------------- 00066 00067 00068 /* 00069 * Resets the MD5 checksum to initial value. 00070 */ 00071 void MD5::reset() 00072 { 00073 A_ = 0x67452301; 00074 B_ = 0xefcdab89; 00075 C_ = 0x98badcfe; 00076 D_ = 0x10325476; 00077 00078 total[0] = 0; 00079 total[1] = 0; 00080 buflen = 0; 00081 } 00082 //--------------------------------------------------------------------------- 00083 00084 00085 /* 00086 * Process the remaining bytes in the internal buffer and the usual 00087 * prolog according to the standard. 00088 */ 00089 void MD5::finish() 00090 { 00091 // Take yet unprocessed bytes into account. 00092 wxUint32 bytes = buflen; 00093 size_t pad; 00094 00095 // Now count remaining bytes. 00096 total[0] += bytes; 00097 if (total[0] < bytes) 00098 ++total[1]; 00099 00100 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; 00101 memcpy(&ibuffer[bytes], fillbuf, pad); 00102 00103 // Put the 64-bit file length in *bits* at the end of the buffer. 00104 *reinterpret_cast<wxUint32*>(&ibuffer[bytes + pad]) = wxUINT32_SWAP_ON_BE(total[0] << 3); 00105 *reinterpret_cast<wxUint32*>(&ibuffer[bytes + pad + 4]) = wxUINT32_SWAP_ON_BE((total[1] << 3) | (total[0] >> 29)); 00106 00107 /* Process last bytes. */ 00108 process_block(ibuffer, bytes + pad + 8); 00109 } 00110 //--------------------------------------------------------------------------- 00111 00112 00113 /* 00114 * Updates the MD5 checksum with specified array of bytes. 00115 */ 00116 void MD5::update(const wxByte* buf, unsigned int len) 00117 { 00118 // When we already have some bits in our internal buffer concatenate both 00119 // inputs first. 00120 if (buflen != 0) 00121 { 00122 size_t left_over = buflen; 00123 size_t add = (128 - left_over > len) ? len : 128 - left_over; 00124 00125 memcpy(&ibuffer[left_over], buf, add); 00126 buflen += add; 00127 00128 if (buflen > 64) 00129 { 00130 process_block(ibuffer, buflen & ~63); 00131 00132 buflen &= 63; 00133 // The regions in the following copy operation cannot overlap. 00134 memcpy(ibuffer, &ibuffer[(left_over + add) & ~63], buflen); 00135 } 00136 00137 buf = static_cast<const wxByte*>(buf) + add; 00138 len -= add; 00139 } 00140 00141 /* Process available complete blocks. */ 00142 if (len >= 64) 00143 { 00144 #if !_STRING_ARCH_unaligned 00145 // To check alignment gcc has an appropriate operator. Other compilers 00146 // don't. 00147 #if __GNUC__ >= 2 00148 #define UNALIGNED_P(p) (((wxUint32) p) % __alignof__(wxUint32) != 0) 00149 #else 00150 #define UNALIGNED_P(p) (((wxUint32) p) % sizeof(wxUint32) != 0) 00151 #endif // __GNUC__ >= 2 00152 00153 if (UNALIGNED_P(buf)) 00154 while (len > 64) 00155 { 00156 process_block(memcpy(ibuffer, buf, 64), 64); 00157 buf = static_cast<const wxByte*>(buf) + 64; 00158 len -= 64; 00159 } 00160 else 00161 #endif // !_STRING_ARCH_unaligned 00162 { 00163 process_block(buf, len & ~63); 00164 buf = static_cast<const wxByte*>(buf) + (len & ~63); 00165 len &= 63; 00166 } 00167 } 00168 00169 // Move remaining bytes in internal buffer. 00170 if (len > 0) 00171 { 00172 size_t left_over = buflen; 00173 00174 memcpy(&ibuffer[left_over], buf, len); 00175 left_over += len; 00176 if (left_over >= 64) 00177 { 00178 process_block(ibuffer, 64); 00179 left_over -= 64; 00180 memcpy(ibuffer, &ibuffer[64], left_over); 00181 } 00182 buflen = left_over; 00183 } 00184 } 00185 //--------------------------------------------------------------------------- 00186 00187 00188 // These are the four functions used in the four steps of the MD5 algorithm 00189 // and defined in the RFC 1321. The first function is a little bit optimized 00190 // (as found in Colin Plumbs public domain implementation). 00191 // #define FF(b, c, d) ((b & c) | (~b & d)) 00192 #define FF(b, c, d) (d ^ (b & (c ^ d))) ///< First fonction of the MD5 algorithm. 00193 #define FG(b, c, d) FF (d, b, c) ///< Second fonction of the MD5 algorithm. 00194 #define FH(b, c, d) (b ^ c ^ d) ///< Third fonction of the MD5 algorithm. 00195 #define FI(b, c, d) (c ^ (b | ~d)) ///< Fourth fonction of the MD5 algorithm. 00196 00197 // The following is from gnupg-1.0.2's cipher/bithelp.h. 00198 /// Rotate a 32 bit integer by n bytes. 00199 #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) 00200 00201 /* 00202 * Process [len] bytes of [buf], accumulating context in [this]. 00203 * It is assumed that len % 64 == 0. 00204 */ 00205 void MD5::process_block(const void* buf, size_t len) 00206 { 00207 wxUint32 correct_words[16]; 00208 const wxUint32* words = static_cast<const wxUint32*>(buf); 00209 size_t nwords = len / sizeof(wxUint32); 00210 const wxUint32* endp = words + nwords; 00211 wxUint32 A = A_; 00212 wxUint32 B = B_; 00213 wxUint32 C = C_; 00214 wxUint32 D = D_; 00215 00216 // First increment the byte count. RFC 1321 specifies the possible length of 00217 // the file up to 2^64 bits. Here we only compute the number of bytes. Do a 00218 // double word increment. 00219 total[0] += len; 00220 if (total[0] < len) 00221 ++total[1]; 00222 00223 // Process all bytes in the buffer with 64 bytes in each round of the loop. 00224 while (words < endp) 00225 { 00226 wxUint32* cwp = correct_words; 00227 wxUint32 A_save = A; 00228 wxUint32 B_save = B; 00229 wxUint32 C_save = C; 00230 wxUint32 D_save = D; 00231 00232 // First round: using the given function, the context and a constant the 00233 // next context is computed. Because the algorithms processing unit is a 00234 // 32-bit word and it is determined to work on words in little endian byte 00235 // order we perhaps have to change the byte order before the computation. 00236 // To reduce the work for the next steps we store the swapped words in the 00237 // array CORRECT_WORDS. 00238 #define OP(a, b, c, d, s, T) \ 00239 do \ 00240 { \ 00241 a += FF(b, c, d) + (*cwp++ = wxUINT32_SWAP_ON_BE(*words)) + T; \ 00242 ++words; \ 00243 a = rol(a, s); \ 00244 a += b; \ 00245 } \ 00246 while (0) 00247 00248 // Before we start, one word to the strange constants. 00249 // They are defined in RFC 1321 as 00250 // 00251 // T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or 00252 // perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' 00253 00254 // Round 1. 00255 OP(A, B, C, D, 7, 0xd76aa478); 00256 OP(D, A, B, C, 12, 0xe8c7b756); 00257 OP(C, D, A, B, 17, 0x242070db); 00258 OP(B, C, D, A, 22, 0xc1bdceee); 00259 OP(A, B, C, D, 7, 0xf57c0faf); 00260 OP(D, A, B, C, 12, 0x4787c62a); 00261 OP(C, D, A, B, 17, 0xa8304613); 00262 OP(B, C, D, A, 22, 0xfd469501); 00263 OP(A, B, C, D, 7, 0x698098d8); 00264 OP(D, A, B, C, 12, 0x8b44f7af); 00265 OP(C, D, A, B, 17, 0xffff5bb1); 00266 OP(B, C, D, A, 22, 0x895cd7be); 00267 OP(A, B, C, D, 7, 0x6b901122); 00268 OP(D, A, B, C, 12, 0xfd987193); 00269 OP(C, D, A, B, 17, 0xa679438e); 00270 OP(B, C, D, A, 22, 0x49b40821); 00271 00272 // For the second to fourth round we have the possibly swapped words 00273 // in CORRECT_WORDS. Redefine the macro to take an additional first 00274 // argument specifying the function to use. 00275 #undef OP 00276 /// Operation for computing the MD5 checksum. 00277 #define OP(f, a, b, c, d, k, s, T) \ 00278 do \ 00279 { \ 00280 a += f (b, c, d) + correct_words[k] + T; \ 00281 a = rol (a, s); \ 00282 a += b; \ 00283 } \ 00284 while (0) 00285 00286 // Round 2. 00287 OP(FG, A, B, C, D, 1, 5, 0xf61e2562); 00288 OP(FG, D, A, B, C, 6, 9, 0xc040b340); 00289 OP(FG, C, D, A, B, 11, 14, 0x265e5a51); 00290 OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); 00291 OP(FG, A, B, C, D, 5, 5, 0xd62f105d); 00292 OP(FG, D, A, B, C, 10, 9, 0x02441453); 00293 OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); 00294 OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); 00295 OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); 00296 OP(FG, D, A, B, C, 14, 9, 0xc33707d6); 00297 OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); 00298 OP(FG, B, C, D, A, 8, 20, 0x455a14ed); 00299 OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); 00300 OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); 00301 OP(FG, C, D, A, B, 7, 14, 0x676f02d9); 00302 OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); 00303 00304 // Round 3. 00305 OP(FH, A, B, C, D, 5, 4, 0xfffa3942); 00306 OP(FH, D, A, B, C, 8, 11, 0x8771f681); 00307 OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); 00308 OP(FH, B, C, D, A, 14, 23, 0xfde5380c); 00309 OP(FH, A, B, C, D, 1, 4, 0xa4beea44); 00310 OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); 00311 OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); 00312 OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); 00313 OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); 00314 OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); 00315 OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); 00316 OP(FH, B, C, D, A, 6, 23, 0x04881d05); 00317 OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); 00318 OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); 00319 OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); 00320 OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); 00321 00322 // Round 4. 00323 OP(FI, A, B, C, D, 0, 6, 0xf4292244); 00324 OP(FI, D, A, B, C, 7, 10, 0x432aff97); 00325 OP(FI, C, D, A, B, 14, 15, 0xab9423a7); 00326 OP(FI, B, C, D, A, 5, 21, 0xfc93a039); 00327 OP(FI, A, B, C, D, 12, 6, 0x655b59c3); 00328 OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); 00329 OP(FI, C, D, A, B, 10, 15, 0xffeff47d); 00330 OP(FI, B, C, D, A, 1, 21, 0x85845dd1); 00331 OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); 00332 OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); 00333 OP(FI, C, D, A, B, 6, 15, 0xa3014314); 00334 OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); 00335 OP(FI, A, B, C, D, 4, 6, 0xf7537e82); 00336 OP(FI, D, A, B, C, 11, 10, 0xbd3af235); 00337 OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); 00338 OP(FI, B, C, D, A, 9, 21, 0xeb86d391); 00339 00340 // Add the starting values of the context. 00341 A += A_save; 00342 B += B_save; 00343 C += C_save; 00344 D += D_save; 00345 } 00346 00347 /* Put checksum in the local context. */ 00348 A_ = A; 00349 B_ = B; 00350 C_ = C; 00351 D_ = D; 00352 } 00353 //--------------------------------------------------------------------------- 00354 00355 00356 /* 00357 * Returns the MD5 checksum value in the first 16 bytes of the given adress. 00358 */ 00359 void* MD5::getValue(void* buffer) const 00360 { 00361 MD5 md5(*this); 00362 md5.finish(); 00363 00364 (reinterpret_cast<wxUint32*>(buffer))[0] = wxUINT32_SWAP_ON_BE(md5.A_); 00365 (reinterpret_cast<wxUint32*>(buffer))[1] = wxUINT32_SWAP_ON_BE(md5.B_); 00366 (reinterpret_cast<wxUint32*>(buffer))[2] = wxUINT32_SWAP_ON_BE(md5.C_); 00367 (reinterpret_cast<wxUint32*>(buffer))[3] = wxUINT32_SWAP_ON_BE(md5.D_); 00368 00369 return buffer; 00370 } 00371 //--------------------------------------------------------------------------- 00372 00373 00374 /* 00375 * Returns the MD5 checksum value. 00376 */ 00377 wxString MD5::getValue(const bool hexInUpperCase) const 00378 { 00379 wxByte b[16]; 00380 wxString s; 00381 wxString h; 00382 // char s[33]; 00383 // char h[5]; 00384 00385 // Sets the pattern for sprintf 00386 if (hexInUpperCase) 00387 h = wxT("%02X"); 00388 else 00389 h = wxT("%02x"); 00390 00391 // Puts the MD5 checksum value in the buffer. 00392 getValue(b); 00393 00394 // Puts the MD5 checksum in a string 00395 for (int i = 0; i < 16; i++) 00396 s += wxString::Format(h, static_cast<unsigned int>(b[i])); 00397 00398 return s; 00399 } 00400 //---------------------------------------------------------------------------

Generated on Sun May 30 13:37:45 2004 for wxChecksums by doxygen 1.3.7