Blender V2.61 - r43446

util_md5.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1999, 2002 Aladdin Enterprises.  All rights reserved.
00003  *
00004  * This software is provided 'as-is', without any express or implied
00005  * warranty.  In no event will the authors be held liable for any damages
00006  * arising from the use of this software.
00007  *
00008  * Permission is granted to anyone to use this software for any purpose,
00009  * including commercial applications, and to alter it and redistribute it
00010  * freely, subject to the following restrictions:
00011  *
00012  * 1. The origin of this software must not be misrepresented; you must not
00013  *  claim that you wrote the original software. If you use this software
00014  *  in a product, an acknowledgment in the product documentation would be
00015  *  appreciated but is not required.
00016  * 2. Altered source versions must be plainly marked as such, and must not be
00017  *  misrepresented as being the original software.
00018  * 3. This notice may not be removed or altered from any source distribution.
00019  *
00020  * L. Peter Deutsch
00021  * ghost@aladdin.com
00022  */
00023 
00024 /* Minor modifications done to remove some code and change style. */
00025 
00026 #include "util_md5.h"
00027 
00028 #include <string.h>
00029 #include <stdio.h>
00030 
00031 CCL_NAMESPACE_BEGIN
00032 
00033 #define T_MASK ((uint32_t)~0)
00034 #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
00035 #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
00036 #define T3  0x242070db
00037 #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
00038 #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
00039 #define T6  0x4787c62a
00040 #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
00041 #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
00042 #define T9  0x698098d8
00043 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
00044 #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
00045 #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
00046 #define T13 0x6b901122
00047 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
00048 #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
00049 #define T16 0x49b40821
00050 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
00051 #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
00052 #define T19 0x265e5a51
00053 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
00054 #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
00055 #define T22 0x02441453
00056 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
00057 #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
00058 #define T25 0x21e1cde6
00059 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
00060 #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
00061 #define T28 0x455a14ed
00062 #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
00063 #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
00064 #define T31 0x676f02d9
00065 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
00066 #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
00067 #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
00068 #define T35 0x6d9d6122
00069 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
00070 #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
00071 #define T38 0x4bdecfa9
00072 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
00073 #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
00074 #define T41 0x289b7ec6
00075 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
00076 #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
00077 #define T44 0x04881d05
00078 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
00079 #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
00080 #define T47 0x1fa27cf8
00081 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
00082 #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
00083 #define T50 0x432aff97
00084 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
00085 #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
00086 #define T53 0x655b59c3
00087 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
00088 #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
00089 #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
00090 #define T57 0x6fa87e4f
00091 #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
00092 #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
00093 #define T60 0x4e0811a1
00094 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
00095 #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
00096 #define T63 0x2ad7d2bb
00097 #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
00098 
00099 void MD5Hash::process(const uint8_t *data /*[64]*/)
00100 {
00101     uint32_t
00102     a = abcd[0], b = abcd[1],
00103     c = abcd[2], d = abcd[3];
00104     uint32_t t;
00105     /* Define storage for little-endian or both types of CPUs. */
00106     uint32_t xbuf[16];
00107     const uint32_t *X;
00108 
00109     {
00110         /*
00111          * Determine dynamically whether this is a big-endian or
00112          * little-endian machine, since we can use a more efficient
00113          * algorithm on the latter.
00114          */
00115         static const int w = 1;
00116 
00117         if(*((const uint8_t *)&w)) /* dynamic little-endian */
00118         {
00119             /*
00120              * On little-endian machines, we can process properly aligned
00121              * data without copying it.
00122              */
00123             if(!((data - (const uint8_t *)0) & 3)) {
00124                 /* data are properly aligned */
00125                 X = (const uint32_t *)data;
00126             }
00127             else {
00128             /* not aligned */
00129             memcpy(xbuf, data, 64);
00130             X = xbuf;
00131             }
00132         }
00133         else { /* dynamic big-endian */
00134             /*
00135              * On big-endian machines, we must arrange the bytes in the
00136              * right order.
00137              */
00138             const uint8_t *xp = data;
00139             int i;
00140 
00141             X = xbuf;       /* (dynamic only) */
00142             for(i = 0; i < 16; ++i, xp += 4)
00143             xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
00144         }
00145     }
00146 
00147 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
00148 
00149     /* Round 1. */
00150     /* Let [abcd k s i] denote the operation
00151        a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
00152 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
00153 #define SET(a, b, c, d, k, s, Ti)\
00154   t = a + F(b,c,d) + X[k] + Ti;\
00155   a = ROTATE_LEFT(t, s) + b
00156     /* Do the following 16 operations. */
00157     SET(a, b, c, d,  0,  7,  T1);
00158     SET(d, a, b, c,  1, 12,  T2);
00159     SET(c, d, a, b,  2, 17,  T3);
00160     SET(b, c, d, a,  3, 22,  T4);
00161     SET(a, b, c, d,  4,  7,  T5);
00162     SET(d, a, b, c,  5, 12,  T6);
00163     SET(c, d, a, b,  6, 17,  T7);
00164     SET(b, c, d, a,  7, 22,  T8);
00165     SET(a, b, c, d,  8,  7,  T9);
00166     SET(d, a, b, c,  9, 12, T10);
00167     SET(c, d, a, b, 10, 17, T11);
00168     SET(b, c, d, a, 11, 22, T12);
00169     SET(a, b, c, d, 12,  7, T13);
00170     SET(d, a, b, c, 13, 12, T14);
00171     SET(c, d, a, b, 14, 17, T15);
00172     SET(b, c, d, a, 15, 22, T16);
00173 #undef SET
00174 
00175      /* Round 2. */
00176      /* Let [abcd k s i] denote the operation
00177           a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
00178 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
00179 #define SET(a, b, c, d, k, s, Ti)\
00180   t = a + G(b,c,d) + X[k] + Ti;\
00181   a = ROTATE_LEFT(t, s) + b
00182      /* Do the following 16 operations. */
00183     SET(a, b, c, d,  1,  5, T17);
00184     SET(d, a, b, c,  6,  9, T18);
00185     SET(c, d, a, b, 11, 14, T19);
00186     SET(b, c, d, a,  0, 20, T20);
00187     SET(a, b, c, d,  5,  5, T21);
00188     SET(d, a, b, c, 10,  9, T22);
00189     SET(c, d, a, b, 15, 14, T23);
00190     SET(b, c, d, a,  4, 20, T24);
00191     SET(a, b, c, d,  9,  5, T25);
00192     SET(d, a, b, c, 14,  9, T26);
00193     SET(c, d, a, b,  3, 14, T27);
00194     SET(b, c, d, a,  8, 20, T28);
00195     SET(a, b, c, d, 13,  5, T29);
00196     SET(d, a, b, c,  2,  9, T30);
00197     SET(c, d, a, b,  7, 14, T31);
00198     SET(b, c, d, a, 12, 20, T32);
00199 #undef SET
00200 
00201      /* Round 3. */
00202      /* Let [abcd k s t] denote the operation
00203           a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
00204 #define H(x, y, z) ((x) ^ (y) ^ (z))
00205 #define SET(a, b, c, d, k, s, Ti)\
00206   t = a + H(b,c,d) + X[k] + Ti;\
00207   a = ROTATE_LEFT(t, s) + b
00208      /* Do the following 16 operations. */
00209     SET(a, b, c, d,  5,  4, T33);
00210     SET(d, a, b, c,  8, 11, T34);
00211     SET(c, d, a, b, 11, 16, T35);
00212     SET(b, c, d, a, 14, 23, T36);
00213     SET(a, b, c, d,  1,  4, T37);
00214     SET(d, a, b, c,  4, 11, T38);
00215     SET(c, d, a, b,  7, 16, T39);
00216     SET(b, c, d, a, 10, 23, T40);
00217     SET(a, b, c, d, 13,  4, T41);
00218     SET(d, a, b, c,  0, 11, T42);
00219     SET(c, d, a, b,  3, 16, T43);
00220     SET(b, c, d, a,  6, 23, T44);
00221     SET(a, b, c, d,  9,  4, T45);
00222     SET(d, a, b, c, 12, 11, T46);
00223     SET(c, d, a, b, 15, 16, T47);
00224     SET(b, c, d, a,  2, 23, T48);
00225 #undef SET
00226 
00227      /* Round 4. */
00228      /* Let [abcd k s t] denote the operation
00229           a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
00230 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
00231 #define SET(a, b, c, d, k, s, Ti)\
00232   t = a + I(b,c,d) + X[k] + Ti;\
00233   a = ROTATE_LEFT(t, s) + b
00234      /* Do the following 16 operations. */
00235     SET(a, b, c, d,  0,  6, T49);
00236     SET(d, a, b, c,  7, 10, T50);
00237     SET(c, d, a, b, 14, 15, T51);
00238     SET(b, c, d, a,  5, 21, T52);
00239     SET(a, b, c, d, 12,  6, T53);
00240     SET(d, a, b, c,  3, 10, T54);
00241     SET(c, d, a, b, 10, 15, T55);
00242     SET(b, c, d, a,  1, 21, T56);
00243     SET(a, b, c, d,  8,  6, T57);
00244     SET(d, a, b, c, 15, 10, T58);
00245     SET(c, d, a, b,  6, 15, T59);
00246     SET(b, c, d, a, 13, 21, T60);
00247     SET(a, b, c, d,  4,  6, T61);
00248     SET(d, a, b, c, 11, 10, T62);
00249     SET(c, d, a, b,  2, 15, T63);
00250     SET(b, c, d, a,  9, 21, T64);
00251 #undef SET
00252 
00253      /* Then perform the following additions. (That is increment each
00254         of the four registers by the value it had before this block
00255         was started.) */
00256     abcd[0] += a;
00257     abcd[1] += b;
00258     abcd[2] += c;
00259     abcd[3] += d;
00260 }
00261 
00262 MD5Hash::MD5Hash()
00263 {
00264     count[0] = count[1] = 0;
00265     abcd[0] = 0x67452301;
00266     abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
00267     abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
00268     abcd[3] = 0x10325476;
00269 }
00270 
00271 MD5Hash::~MD5Hash()
00272 {
00273 }
00274 
00275 void MD5Hash::append(const uint8_t *data, int nbytes)
00276 {
00277     const uint8_t *p = data;
00278     int left = nbytes;
00279     int offset = (count[0] >> 3) & 63;
00280     uint32_t nbits = (uint32_t)(nbytes << 3);
00281 
00282     if(nbytes <= 0)
00283         return;
00284 
00285     /* Update the message length. */
00286     count[1] += nbytes >> 29;
00287     count[0] += nbits;
00288     if(count[0] < nbits)
00289         count[1]++;
00290 
00291     /* Process an initial partial block. */
00292     if(offset) {
00293         int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
00294 
00295         memcpy(buf + offset, p, copy);
00296         if(offset + copy < 64)
00297             return;
00298         p += copy;
00299         left -= copy;
00300         process(buf);
00301     }
00302 
00303     /* Process full blocks. */
00304     for(; left >= 64; p += 64, left -= 64)
00305         process(p);
00306 
00307     /* Process a final partial block. */
00308     if(left)
00309         memcpy(buf, p, left);
00310 }
00311 
00312 bool MD5Hash::append_file(const string& filepath)
00313 {
00314     FILE *f = fopen(filepath.c_str(), "rb");
00315 
00316     if(!f) {
00317         fprintf(stderr, "MD5: failed to open file %s\n", filepath.c_str());
00318         return false;
00319     }
00320 
00321     const size_t buffer_size = 1024;
00322     uint8_t buffer[buffer_size];
00323     size_t n;
00324 
00325     do {
00326         n = fread(buffer, 1, buffer_size, f);
00327         append(buffer, n);
00328     } while(n == buffer_size);
00329 
00330     bool success = (ferror(f) == 0);
00331 
00332     fclose(f);
00333     
00334     return success;
00335 }
00336 
00337 void MD5Hash::finish(uint8_t digest[16])
00338 {
00339     static const uint8_t pad[64] = {
00340         0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00341         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00342         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00343         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
00344 
00345     uint8_t data[8];
00346     int i;
00347 
00348     /* Save the length before padding. */
00349     for(i = 0; i < 8; ++i)
00350         data[i] = (uint8_t)(count[i >> 2] >> ((i & 3) << 3));
00351 
00352     /* Pad to 56 bytes mod 64. */
00353     append(pad, ((55 - (count[0] >> 3)) & 63) + 1);
00354     /* Append the length. */
00355     append(data, 8);
00356 
00357     for(i = 0; i < 16; ++i)
00358         digest[i] = (uint8_t)(abcd[i >> 2] >> ((i & 3) << 3));
00359 }
00360 
00361 string MD5Hash::get_hex()
00362 {
00363     uint8_t digest[16];
00364     char buf[16*2+1];
00365 
00366     finish(digest);
00367 
00368     for(int i=0; i<16; i++)
00369         sprintf(buf + i*2, "%02X", digest[i]);
00370     buf[sizeof(buf)-1] = '\0';
00371     
00372     return string(buf);
00373 }
00374 
00375 CCL_NAMESPACE_END
00376