libStatGen Software
1
|
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