libStatGen Software  1
CSG_MD5.h
00001 //
00002 // This is a C++ friendly, limited use MD5 checksum copied
00003 // from the reference implementation at http://www.ietf.org/rfc/rfc1321.txt
00004 //
00005 // The sole purpose of this file is to eliminate dependence on the
00006 // openssl MD5 code, which poses a maintenance problem for general
00007 // users trying to build libstatgen.
00008 //
00009 // It is intended to be included solely by GenomeSequence.cpp, which
00010 // needs it to compute the MD5 checksum of chromosomes it is building.
00011 //
00012 
00013 /* MDDRIVER.C - test driver for MD2, MD4 and MD5
00014  */
00015 
00016 /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
00017 rights reserved.
00018 
00019 RSA Data Security, Inc. makes no representations concerning either
00020 the merchantability of this software or the suitability of this
00021 software for any particular purpose. It is provided "as is"
00022 without express or implied warranty of any kind.
00023 
00024 These notices must be retained in any copies of any part of this
00025 documentation and/or software.
00026  */
00027 
00028 #include <stdio.h>
00029 #include <time.h>
00030 #include <string.h>
00031 
00032 /* MD5.H - header file for MD5C.C
00033  */
00034 
00035 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00036 rights reserved.
00037 
00038 License to copy and use this software is granted provided that it
00039 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00040 Algorithm" in all material mentioning or referencing this software
00041 or this function.
00042 
00043 License is also granted to make and use derivative works provided
00044 that such works are identified as "derived from the RSA Data
00045 Security, Inc. MD5 Message-Digest Algorithm" in all material
00046 mentioning or referencing the derived work.
00047 
00048 RSA Data Security, Inc. makes no representations concerning either
00049 the merchantability of this software or the suitability of this
00050 software for any particular purpose. It is provided "as is"
00051 without express or implied warranty of any kind.
00052 
00053 These notices must be retained in any copies of any part of this
00054 documentation and/or software.
00055  */
00056 
00057 #include <stdint.h>
00058 
00059 /* MD5 context. */
00060 typedef struct {
00061   uint32_t state[4];                                   /* state (ABCD) */
00062   uint32_t count[2];        /* number of bits, modulo 2^64 (lsb first) */
00063   unsigned char buffer[64];                         /* input buffer */
00064 } MD5_CTX;
00065 
00066 static void MD5Init(MD5_CTX *);
00067 static void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
00068 static void MD5Final(unsigned char [16], MD5_CTX *);
00069 
00070 
00071 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
00072  */
00073 
00074 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
00075 rights reserved.
00076 
00077 License to copy and use this software is granted provided that it
00078 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
00079 Algorithm" in all material mentioning or referencing this software
00080 or this function.
00081 
00082 License is also granted to make and use derivative works provided
00083 that such works are identified as "derived from the RSA Data
00084 Security, Inc. MD5 Message-Digest Algorithm" in all material
00085 mentioning or referencing the derived work.
00086 
00087 RSA Data Security, Inc. makes no representations concerning either
00088 the merchantability of this software or the suitability of this
00089 software for any particular purpose. It is provided "as is"
00090 without express or implied warranty of any kind.
00091 
00092 These notices must be retained in any copies of any part of this
00093 documentation and/or software.
00094  */
00095 
00096 /* Constants for MD5Transform routine.
00097  */
00098 
00099 #define S11 7
00100 #define S12 12
00101 #define S13 17
00102 #define S14 22
00103 #define S21 5
00104 #define S22 9
00105 #define S23 14
00106 #define S24 20
00107 #define S31 4
00108 #define S32 11
00109 #define S33 16
00110 #define S34 23
00111 #define S41 6
00112 #define S42 10
00113 #define S43 15
00114 #define S44 21
00115 
00116 typedef unsigned char *POINTER;
00117 
00118 static void MD5Transform(uint32_t [4], unsigned char [64]);
00119 static void Encode(unsigned char *, uint32_t *, unsigned int);
00120 static void Decode(uint32_t *, unsigned char *, unsigned int);
00121 static void MD5_memcpy(POINTER, POINTER, unsigned int);
00122 static void MD5_memset(POINTER, int, unsigned int);
00123 
00124 static unsigned char PADDING[64] = {
00125   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00126   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00127   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00128 };
00129 
00130 /* F, G, H and I are basic MD5 functions.
00131  */
00132 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
00133 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
00134 #define H(x, y, z) ((x) ^ (y) ^ (z))
00135 #define I(x, y, z) ((y) ^ ((x) | (~z)))
00136 
00137 /* ROTATE_LEFT rotates x left n bits.
00138  */
00139 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00140 
00141 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00142 Rotation is separate from addition to prevent recomputation.
00143  */
00144 #define FF(a, b, c, d, x, s, ac) { \
00145  (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
00146  (a) = ROTATE_LEFT ((a), (s)); \
00147  (a) += (b); \
00148   }
00149 #define GG(a, b, c, d, x, s, ac) { \
00150  (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
00151  (a) = ROTATE_LEFT ((a), (s)); \
00152  (a) += (b); \
00153   }
00154 #define HH(a, b, c, d, x, s, ac) { \
00155  (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
00156  (a) = ROTATE_LEFT ((a), (s)); \
00157  (a) += (b); \
00158   }
00159 #define II(a, b, c, d, x, s, ac) { \
00160  (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
00161  (a) = ROTATE_LEFT ((a), (s)); \
00162  (a) += (b); \
00163   }
00164 
00165 /* MD5 initialization. Begins an MD5 operation, writing a new context.
00166  */
00167 static void MD5Init ( MD5_CTX *context)                                        /* context */
00168 {
00169   context->count[0] = context->count[1] = 0;
00170   /* Load magic initialization constants.
00171 */
00172   context->state[0] = 0x67452301;
00173   context->state[1] = 0xefcdab89;
00174   context->state[2] = 0x98badcfe;
00175   context->state[3] = 0x10325476;
00176 }
00177 
00178 /* MD5 block update operation. Continues an MD5 message-digest
00179   operation, processing another message block, and updating the
00180   context.
00181  */
00182 static void MD5Update (
00183 MD5_CTX *context,                                        /* context */
00184 unsigned char *input,                                /* input block */
00185 unsigned int inputLen)                     /* length of input block */
00186 {
00187   unsigned int i, index, partLen;
00188 
00189   /* Compute number of bytes mod 64 */
00190   index = (unsigned int)((context->count[0] >> 3) & 0x3F);
00191 
00192   /* Update number of bits */
00193   if ((context->count[0] += ((uint32_t)inputLen << 3))
00194    < ((uint32_t)inputLen << 3))
00195  context->count[1]++;
00196   context->count[1] += ((uint32_t)inputLen >> 29);
00197 
00198   partLen = 64 - index;
00199 
00200   /* Transform as many times as possible.
00201 */
00202   if (inputLen >= partLen) {
00203  MD5_memcpy
00204    ((POINTER)&context->buffer[index], (POINTER)input, partLen);
00205  MD5Transform (context->state, context->buffer);
00206 
00207  for (i = partLen; i + 63 < inputLen; i += 64)
00208    MD5Transform (context->state, &input[i]);
00209 
00210  index = 0;
00211   }
00212   else
00213  i = 0;
00214 
00215   /* Buffer remaining input */
00216   MD5_memcpy
00217  ((POINTER)&context->buffer[index], (POINTER)&input[i],
00218   inputLen-i);
00219 }
00220 
00221 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
00222   the message digest and zeroizing the context.
00223  */
00224 static void MD5Final (
00225 unsigned char digest[16],                         /* message digest */
00226 MD5_CTX *context)                                       /* context */
00227 {
00228   unsigned char bits[8];
00229   unsigned int index, padLen;
00230 
00231   /* Save number of bits */
00232   Encode (bits, context->count, 8);
00233 
00234   /* Pad out to 56 mod 64.
00235 */
00236   index = (unsigned int)((context->count[0] >> 3) & 0x3f);
00237   padLen = (index < 56) ? (56 - index) : (120 - index);
00238   MD5Update (context, PADDING, padLen);
00239 
00240   /* Append length (before padding) */
00241   MD5Update (context, bits, 8);
00242 
00243   /* Store state in digest */
00244   Encode (digest, context->state, 16);
00245 
00246   /* Zeroize sensitive information.
00247 */
00248   MD5_memset ((POINTER)context, 0, sizeof (*context));
00249 }
00250 
00251 /* MD5 basic transformation. Transforms state based on block.
00252  */
00253 static void MD5Transform (
00254 uint32_t state[4],
00255 unsigned char block[64])
00256 {
00257   uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
00258 
00259   Decode (x, block, 64);
00260 
00261   /* Round 1 */
00262   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
00263   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
00264   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
00265   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
00266   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
00267   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
00268   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
00269   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
00270   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
00271   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
00272   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
00273   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
00274   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
00275   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
00276   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
00277   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
00278 
00279  /* Round 2 */
00280   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
00281   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
00282   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
00283   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
00284   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
00285   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
00286   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
00287   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
00288   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
00289   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
00290   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
00291   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
00292   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
00293   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
00294   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
00295   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
00296 
00297   /* Round 3 */
00298   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
00299   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
00300   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
00301   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
00302   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
00303   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
00304   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
00305   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
00306   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
00307   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
00308   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
00309   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
00310   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
00311   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
00312   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
00313   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
00314 
00315   /* Round 4 */
00316   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
00317   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
00318   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
00319   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
00320   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
00321   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
00322   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
00323   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
00324   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
00325   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
00326   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
00327   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
00328   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
00329   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
00330   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
00331   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
00332 
00333   state[0] += a;
00334   state[1] += b;
00335   state[2] += c;
00336   state[3] += d;
00337 
00338   /* Zeroize sensitive information.
00339 */
00340   MD5_memset ((POINTER)x, 0, sizeof (x));
00341 }
00342 
00343 /* Encodes input (uint32_t) into output (unsigned char). Assumes len is
00344   a multiple of 4.
00345  */
00346 static void Encode (
00347 unsigned char *output,
00348 uint32_t *input,
00349 unsigned int len)
00350 {
00351   unsigned int i, j;
00352 
00353   for (i = 0, j = 0; j < len; i++, j += 4) {
00354  output[j] = (unsigned char)(input[i] & 0xff);
00355  output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
00356  output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
00357  output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
00358   }
00359 }
00360 
00361 /* Decodes input (unsigned char) into output (uint32_t). Assumes len is
00362   a multiple of 4.
00363  */
00364 static void Decode (
00365 uint32_t *output,
00366 unsigned char *input,
00367 unsigned int len)
00368 {
00369   unsigned int i, j;
00370 
00371   for (i = 0, j = 0; j < len; i++, j += 4)
00372  output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
00373    (((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
00374 }
00375 
00376 /* Note: Replace "for loop" with standard memcpy if possible.
00377  */
00378 
00379 static void MD5_memcpy (
00380 POINTER output,
00381 POINTER input,
00382 unsigned int len)
00383 {
00384   unsigned int i;
00385 
00386   for (i = 0; i < len; i++)
00387        output[i] = input[i];
00388 }
00389 
00390 /* Note: Replace "for loop" with standard memset if possible.
00391  */
00392 static void MD5_memset (
00393 POINTER output,
00394 int value,
00395 unsigned int len)
00396 {
00397   unsigned int i;
00398 
00399   for (i = 0; i < len; i++)
00400  ((char *)output)[i] = (char)value;
00401 }
00402 
00403 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends