Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

niml_md5.c

Go to the documentation of this file.
00001 #include "niml_private.h"
00002 
00003 /*************************************************************************/
00004 /************************* Stuff for MD5 hashing *************************/
00005 /** [Most are not actually used in NIML, but are here for completeness] **/
00006 /*************************************************************************/
00007 
00008 /**********************************************************************
00009  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All    *
00010  * rights reserved.                                                   *
00011  *                                                                    *
00012  * License to copy and use this software is granted provided that it  *
00013  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest   *
00014  * Algorithm" in all material mentioning or referencing this software *
00015  * or this function.                                                  *
00016  *                                                                    *
00017  * License is also granted to make and use derivative works provided  *
00018  * that such works are identified as "derived from the RSA Data       *
00019  * Security, Inc. MD5 Message-Digest Algorithm" in all material       *
00020  * mentioning or referencing the derived work.                        *
00021  *                                                                    *
00022  * RSA Data Security, Inc. makes no representations concerning either *
00023  * the merchantability of this software or the suitability of this    *
00024  * software for any particular purpose. It is provided "as is"        *
00025  * without express or implied warranty of any kind.                   *
00026  *                                                                    *
00027  * These notices must be retained in any copies of any part of this   *
00028  * documentation and/or software.                                     *
00029  **********************************************************************/
00030 
00031 /*======= Modified by RWCox for inclusion in the NIML package ========*/
00032 /*------- These changes are released to the public domain     --------*/
00033 
00034 /* prototypes for some internal functions */
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 /* Constants for MD5Transform routine.  */
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 /* F, G, H and I are basic MD5 functions.  */
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 /* ROTATE_LEFT rotates x left n bits.  */
00073 
00074 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00075 
00076 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00077    Rotation is separate from addition to prevent recomputation.  */
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 /*! MD5 initialization. Begins an MD5 operation, writing a new context.
00105 ------------------------------------------------------------------------*/
00106 
00107 void MD5Init (MD5_CTX *context)
00108 {
00109   context->count[0] = context->count[1] = 0;
00110 
00111   /* Load magic initialization constants */
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 /*! MD5 block update operation. Continues an MD5 message-digest
00121    operation, processing another message block, and updating the
00122    context.
00123 ------------------------------------------------------------------------*/
00124 
00125 void MD5Update (MD5_CTX *context, unsigned char *input,
00126                                          unsigned int inputLen  )
00127 {
00128   unsigned int i, index, partLen;
00129 
00130   /* Compute number of bytes mod 64 */
00131 
00132   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00133 
00134   /* Update number of bits */
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   /* Transform as many times as possible.  */
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   /* Buffer remaining input */
00160 
00161   memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i],
00162           inputLen-i);
00163 }
00164 
00165 /*----------------------------------------------------------------------*/
00166 /*! MD5 finalization. Ends an MD5 message-digest operation, writing the
00167    the message digest and zeroizing the context.
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   /* Save number of bits */
00176 
00177   Encode (bits, context->count, 8);
00178 
00179   /* Pad out to 56 mod 64.  */
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   /* Append length (before padding) */
00186 
00187   MD5Update (context, bits, 8);
00188 
00189   /* Store state in digest */
00190 
00191   Encode (digest, context->state, 16);
00192 
00193   /* Zeroize sensitive information. */
00194 
00195   memset ((POINTER)context, 0, sizeof (*context));
00196 }
00197 
00198 /*----------------------------------------------------------------------*/
00199 /*! MD5 basic transformation. Transforms state based on block.
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   /* Round 1 */
00209 
00210   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00211   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00212   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00213   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00214   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00215   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00216   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00217   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00218   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00219   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00220   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00221   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00222   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00223   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00224   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00225   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00226 
00227   /* Round 2 */
00228 
00229   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00230   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00231   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00232   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00233   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00234   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00235   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00236   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00237   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00238   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00239   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00240   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
00241   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00242   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
00243   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
00244   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00245 
00246   /* Round 3 */
00247 
00248   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
00249   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
00250   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00251   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00252   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
00253   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
00254   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
00255   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00256   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00257   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
00258   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
00259   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
00260   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
00261   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00262   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00263   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
00264 
00265   /* Round 4 */
00266 
00267   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
00268   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
00269   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00270   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
00271   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00272   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
00273   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00274   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
00275   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
00276   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00277   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
00278   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00279   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
00280   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00281   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
00282   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
00283 
00284   state[0] += a;
00285   state[1] += b;
00286   state[2] += c;
00287   state[3] += d;
00288 
00289   /* Zeroize sensitive information. */
00290 
00291   memset ((POINTER)x, 0, sizeof (x));
00292 }
00293 
00294 /*----------------------------------------------------------------------*/
00295 /*! Encodes input (UINT4) into output (unsigned char). Assumes len is
00296    a multiple of 4.
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 /*! Decodes input (unsigned char) into output (UINT4). Assumes len is
00313    a multiple of 4.
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    The stuff below is some MD5 interface routines, by RWCox
00327 ========================================================================*/
00328 
00329 /*----------------------------------------------------------------------*/
00330 /*! Function to print a 128 bit digest into a static 32 char string.
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 /*! Digest an array and returns the printable string of the result,
00350     stored in a static array (length=32+1 bytes).
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 /*! Digest an array and returns the printable string of the result,
00369     stored in a malloc()-ed array (length=32+1 bytes).
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 /*! Digest a C string and returns the printable string of the result,
00382     stored in a static array (length=32+1 bytes).
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 /*! Digest a C string and returns the printable string of the result,
00393     stored in a malloc()-ed array (length=32+1 bytes).
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 /*! Digests a file and prints the result, stored in a static array
00404     (length=32+1 bytes).
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 /*! Digests a file and prints the result, stored in a malloc()-ed array
00430     (length=32+1 bytes).
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 /*! Convert a MD5 hex string to a Base64-ed string.
00444     * strlen(result) is 22 instead of 32
00445     * result is malloc()-ed and should be free()-d when appropriate
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' ;                           /* remove trailing "==" */
00455    if( isspace(b64[nb64-4]) ) b64[nb64-4]='\0' ;
00456    return (char *)b64 ;
00457 }
00458 
00459 /*----------------------------------------------------------------------------*/
00460 /*! Return the MD5 hash of an array as a Base64 string, instead of a hex
00461     string.
00462     * strlen(result) is 22 instead of 32
00463     * result is malloc()-ed and should be free()-d when appropriate
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 /*! Return the MD5 hash of a C string as a Base64 string, instead of a hex
00482     string.
00483     * strlen(result) is 22 instead of 32
00484     * result is malloc()-ed and should be free()-d when appropriate
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 /*! Return the MD5 hash of a file as a Base64 string, instead of a hex
00495     string.
00496     - strlen(result) is 22 instead of 32
00497     - result is malloc()-ed and should be free()-d when appropriate
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 }
 

Powered by Plone

This site conforms to the following standards: