00001 #include "niml_private.h"
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 static void MD5Transform (UINT4 [4], unsigned char [64]);
00037 static void Encode (unsigned char *, UINT4 *, unsigned int);
00038 static void Decode (UINT4 *, unsigned char *, unsigned int);
00039 
00040 
00041 
00042 #define S11 7
00043 #define S12 12
00044 #define S13 17
00045 #define S14 22
00046 #define S21 5
00047 #define S22 9
00048 #define S23 14
00049 #define S24 20
00050 #define S31 4
00051 #define S32 11
00052 #define S33 16
00053 #define S34 23
00054 #define S41 6
00055 #define S42 10
00056 #define S43 15
00057 #define S44 21
00058 
00059 static unsigned char PADDING[64] = {
00060   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00061   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00062   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00063 };
00064 
00065 
00066 
00067 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00068 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00069 #define H(x, y, z) ((x) ^ (y) ^ (z))
00070 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00071 
00072 
00073 
00074 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00075 
00076 
00077 
00078 
00079 #define FF(a, b, c, d, x, s, ac) { \
00080  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
00081  (a) = ROTATE_LEFT ((a), (s)); \
00082  (a) += (b); \
00083   }
00084 
00085 #define GG(a, b, c, d, x, s, ac) { \
00086  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
00087  (a) = ROTATE_LEFT ((a), (s)); \
00088  (a) += (b); \
00089   }
00090 
00091 #define HH(a, b, c, d, x, s, ac) { \
00092  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
00093  (a) = ROTATE_LEFT ((a), (s)); \
00094  (a) += (b); \
00095   }
00096 
00097 #define II(a, b, c, d, x, s, ac) { \
00098  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
00099  (a) = ROTATE_LEFT ((a), (s)); \
00100  (a) += (b); \
00101   }
00102 
00103 
00104 
00105 
00106 
00107 void MD5Init (MD5_CTX *context)
00108 {
00109   context->count[0] = context->count[1] = 0;
00110 
00111   
00112 
00113   context->state[0] = 0x67452301;
00114   context->state[1] = 0xefcdab89;
00115   context->state[2] = 0x98badcfe;
00116   context->state[3] = 0x10325476;
00117 }
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 void MD5Update (MD5_CTX *context, unsigned char *input,
00126                                          unsigned int inputLen  )
00127 {
00128   unsigned int i, index, partLen;
00129 
00130   
00131 
00132   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00133 
00134   
00135 
00136   if( (context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3) )
00137     context->count[1]++;
00138 
00139   context->count[1] += ((UINT4)inputLen >> 29);
00140 
00141   partLen = 64 - index;
00142 
00143   
00144 
00145   if (inputLen >= partLen) {
00146 
00147    memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00148 
00149    MD5Transform (context->state, context->buffer);
00150 
00151    for (i = partLen; i + 63 < inputLen; i += 64)
00152      MD5Transform (context->state, &input[i]);
00153 
00154    index = 0;
00155   }
00156   else
00157    i = 0;
00158 
00159   
00160 
00161   memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i],
00162           inputLen-i);
00163 }
00164 
00165 
00166 
00167 
00168 
00169 
00170 void MD5Final (unsigned char digest[16], MD5_CTX *context)
00171 {
00172   unsigned char bits[8];
00173   unsigned int index, padLen;
00174 
00175   
00176 
00177   Encode (bits, context->count, 8);
00178 
00179   
00180 
00181   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00182   padLen = (index < 56) ? (56 - index) : (120 - index);
00183   MD5Update (context, PADDING, padLen);
00184 
00185   
00186 
00187   MD5Update (context, bits, 8);
00188 
00189   
00190 
00191   Encode (digest, context->state, 16);
00192 
00193   
00194 
00195   memset ((POINTER)context, 0, sizeof (*context));
00196 }
00197 
00198 
00199 
00200 
00201 
00202 static void MD5Transform (UINT4 state[4], unsigned char block[64])
00203 {
00204   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00205 
00206   Decode (x, block, 64);
00207 
00208   
00209 
00210   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); 
00211   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); 
00212   FF (c, d, a, b, x[ 2], S13, 0x242070db); 
00213   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); 
00214   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); 
00215   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); 
00216   FF (c, d, a, b, x[ 6], S13, 0xa8304613); 
00217   FF (b, c, d, a, x[ 7], S14, 0xfd469501); 
00218   FF (a, b, c, d, x[ 8], S11, 0x698098d8); 
00219   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); 
00220   FF (c, d, a, b, x[10], S13, 0xffff5bb1); 
00221   FF (b, c, d, a, x[11], S14, 0x895cd7be); 
00222   FF (a, b, c, d, x[12], S11, 0x6b901122); 
00223   FF (d, a, b, c, x[13], S12, 0xfd987193); 
00224   FF (c, d, a, b, x[14], S13, 0xa679438e); 
00225   FF (b, c, d, a, x[15], S14, 0x49b40821); 
00226 
00227   
00228 
00229   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); 
00230   GG (d, a, b, c, x[ 6], S22, 0xc040b340); 
00231   GG (c, d, a, b, x[11], S23, 0x265e5a51); 
00232   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); 
00233   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); 
00234   GG (d, a, b, c, x[10], S22,  0x2441453); 
00235   GG (c, d, a, b, x[15], S23, 0xd8a1e681); 
00236   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); 
00237   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); 
00238   GG (d, a, b, c, x[14], S22, 0xc33707d6); 
00239   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); 
00240   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); 
00241   GG (a, b, c, d, x[13], S21, 0xa9e3e905); 
00242   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); 
00243   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); 
00244   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); 
00245 
00246   
00247 
00248   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); 
00249   HH (d, a, b, c, x[ 8], S32, 0x8771f681); 
00250   HH (c, d, a, b, x[11], S33, 0x6d9d6122); 
00251   HH (b, c, d, a, x[14], S34, 0xfde5380c); 
00252   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); 
00253   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); 
00254   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); 
00255   HH (b, c, d, a, x[10], S34, 0xbebfbc70); 
00256   HH (a, b, c, d, x[13], S31, 0x289b7ec6); 
00257   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); 
00258   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); 
00259   HH (b, c, d, a, x[ 6], S34,  0x4881d05); 
00260   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); 
00261   HH (d, a, b, c, x[12], S32, 0xe6db99e5); 
00262   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); 
00263   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); 
00264 
00265   
00266 
00267   II (a, b, c, d, x[ 0], S41, 0xf4292244); 
00268   II (d, a, b, c, x[ 7], S42, 0x432aff97); 
00269   II (c, d, a, b, x[14], S43, 0xab9423a7); 
00270   II (b, c, d, a, x[ 5], S44, 0xfc93a039); 
00271   II (a, b, c, d, x[12], S41, 0x655b59c3); 
00272   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); 
00273   II (c, d, a, b, x[10], S43, 0xffeff47d); 
00274   II (b, c, d, a, x[ 1], S44, 0x85845dd1); 
00275   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); 
00276   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); 
00277   II (c, d, a, b, x[ 6], S43, 0xa3014314); 
00278   II (b, c, d, a, x[13], S44, 0x4e0811a1); 
00279   II (a, b, c, d, x[ 4], S41, 0xf7537e82); 
00280   II (d, a, b, c, x[11], S42, 0xbd3af235); 
00281   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); 
00282   II (b, c, d, a, x[ 9], S44, 0xeb86d391); 
00283 
00284   state[0] += a;
00285   state[1] += b;
00286   state[2] += c;
00287   state[3] += d;
00288 
00289   
00290 
00291   memset ((POINTER)x, 0, sizeof (x));
00292 }
00293 
00294 
00295 
00296 
00297 
00298 
00299 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
00300 {
00301   unsigned int i, j;
00302 
00303   for (i = 0, j = 0; j < len; i++, j += 4) {
00304     output[j] = (unsigned char)(input[i] & 0xff);
00305     output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00306     output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00307     output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00308   }
00309 }
00310 
00311 
00312 
00313 
00314 
00315 
00316 static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
00317 {
00318   unsigned int i, j;
00319 
00320   for (i = 0, j = 0; j < len; i++, j += 4)
00321     output[i] = ((UINT4)input[j])          | (((UINT4)input[j+1]) << 8) |
00322                (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24) ;
00323 }
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 static char * MD5_static_printf( unsigned char digest[16] )
00334 {
00335   static char st[33] ;
00336 
00337   sprintf(st,
00338      "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" ,
00339      digest[0] , digest[1] , digest[2] , digest[3] , digest[4] ,
00340      digest[5] , digest[6] , digest[7] , digest[8] , digest[9] ,
00341      digest[10], digest[11], digest[12], digest[13], digest[14],
00342      digest[15]
00343     ) ;
00344 
00345   return st ;
00346 }
00347 
00348 
00349 
00350 
00351 
00352 
00353 char * MD5_static_array( int n , char *bytes )
00354 {
00355    MD5_CTX context;
00356    unsigned char digest[16];
00357 
00358    if( n < 0 || bytes == NULL ) return NULL ;
00359 
00360    MD5Init( &context ) ;
00361    MD5Update( &context, (unsigned char *)bytes, n ) ;
00362    MD5Final( digest, &context ) ;
00363 
00364    return MD5_static_printf(digest) ;
00365 }
00366 
00367 
00368 
00369 
00370 
00371 
00372 char * MD5_malloc_array( int n , char *bytes )
00373 {
00374    char *st , *dy ;
00375    st = MD5_static_array( n , bytes ) ;
00376    if( st == NULL ) return NULL ;
00377    dy = (char *) malloc(33) ; strcpy(dy,st) ; return dy ;
00378 }
00379 
00380 
00381 
00382 
00383 
00384 
00385 char * MD5_static_string( char *string )
00386 {
00387    if( string == NULL ) string = "ElvisTheKing" ;
00388    return MD5_static_array( strlen(string) , string ) ;
00389 }
00390 
00391 
00392 
00393 
00394 
00395 
00396 char * MD5_malloc_string( char *string )
00397 {
00398    if( string == NULL ) string = "ElvisTheKing" ;
00399    return MD5_malloc_array( strlen(string)+1 , string ) ;
00400 }
00401 
00402 
00403 
00404 
00405 
00406 
00407 char * MD5_static_file(char *filename)
00408 {
00409   FILE *file;
00410   MD5_CTX context;
00411   int len;
00412   unsigned char buffer[1024] ;
00413   unsigned char digest[16] ;
00414 
00415   if( (file = fopen(filename, "rb")) == NULL ) return NULL ;
00416 
00417   MD5Init( &context ) ;
00418 
00419   while( len = fread(buffer, 1, 1024, file) )
00420       MD5Update( &context, buffer, len ) ;
00421 
00422   MD5Final( digest, &context );
00423   fclose (file);
00424 
00425   return MD5_static_printf( digest ) ;
00426 }
00427 
00428 
00429 
00430 
00431 
00432 
00433 char * MD5_malloc_file(char *filename)
00434 {
00435    char *st , *dy ;
00436 
00437    st = MD5_static_file( filename ) ;
00438    if( st == NULL ) return NULL ;
00439    dy = (char *) malloc(33) ; strcpy(dy,st) ; return dy ;
00440 }
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 static char * MD5_to_B64( unsigned char digest[16] )
00449 {
00450    int nb64=0 ; byte *b64=NULL ;
00451 
00452    B64_to_base64( 16 , (byte *)digest , &nb64 , &b64 ) ;
00453    if( nb64 <= 0 || b64 == NULL ) return NULL ;
00454    b64[nb64-3] = '\0' ;                           
00455    if( isspace(b64[nb64-4]) ) b64[nb64-4]='\0' ;
00456    return (char *)b64 ;
00457 }
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 char * MD5_B64_array( int n , char *bytes )
00467 {
00468    MD5_CTX context;
00469    unsigned char digest[16];
00470 
00471    if( n < 0 || bytes == NULL ) return NULL ;
00472 
00473    MD5Init( &context ) ;
00474    MD5Update( &context, (unsigned char *)bytes, n ) ;
00475    MD5Final( digest, &context ) ;
00476 
00477    return MD5_to_B64( digest ) ;
00478 }
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 char * MD5_B64_string( char *string )
00488 {
00489    if( string == NULL ) string = "ElvisTheKing" ;
00490    return MD5_B64_array( strlen(string) , string ) ;
00491 }
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 char * MD5_B64_file(char *filename)
00501 {
00502   FILE *file;
00503   MD5_CTX context;
00504   int len;
00505   unsigned char buffer[1024] ;
00506   unsigned char digest[16] ;
00507 
00508   if( (file=fopen (filename, "rb")) == NULL ) return NULL ;
00509 
00510   MD5Init( &context ) ;
00511 
00512   while( len = fread(buffer, 1, 1024, file) )
00513       MD5Update( &context, buffer, len ) ;
00514 
00515   MD5Final( digest, &context );
00516   fclose (file);
00517 
00518   return MD5_to_B64( digest ) ;
00519 }