1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1996-2008 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 22 /* 23 * md5 24 */ 25 26 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 27 rights reserved. 28 29 License to copy and use this software is granted provided that it 30 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 31 Method" in all material mentioning or referencing this software 32 or this function. 33 34 License is also granted to make and use derivative works provided 35 that such works are identified as "derived from the RSA Data 36 Security, Inc. MD5 Message-Digest Method" in all material 37 mentioning or referencing the derived work. 38 39 RSA Data Security, Inc. makes no representations concerning either 40 the merchantability of this software or the suitability of this 41 software for any particular purpose. It is provided "as is" 42 without express or implied warranty of any kind. 43 44 These notices must be retained in any copies of any part of this 45 documentation and/or software. 46 */ 47 48 #define md5_description \ 49 "The RSA Data Security, Inc. MD5 Message-Digest Method, 1991-2, \ 50 used with permission. The block count is not printed." 51 #define md5_options "[+(version)?md5 (RSA Data Security, Inc. MD5 Message-Digest, 1991-2) 1996-02-29]" 52 #define md5_match "md5|MD5" 53 #define md5_scale 0 54 55 typedef uint32_t UINT4; 56 57 typedef struct Md5_s 58 { 59 _SUM_PUBLIC_ 60 _SUM_PRIVATE_ 61 UINT4 state[4]; /* state (ABCD) */ 62 UINT4 count[2]; /* # bits handled mod 2^64 (lsb)*/ 63 unsigned char buffer[64]; /* input buffer */ 64 unsigned char digest[16]; /* final digest */ 65 unsigned char digest_sum[16]; /* sum of all digests */ 66 } Md5_t; 67 68 static const unsigned char md5_pad[] = 69 { 70 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 78 }; 79 80 /* 81 * encode input into output 82 * len must be a multiple of 4 83 */ 84 85 static void 86 md5_encode(register unsigned char* output, register UINT4* input, unsigned int len) 87 { 88 register unsigned int i; 89 register unsigned int j; 90 91 for (i = j = 0; j < len; i++, j += 4) 92 { 93 output[j] = (unsigned char)(input[i] & 0xff); 94 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 95 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 96 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 97 } 98 } 99 100 /* 101 * decode input into output 102 * len must be a multiple of 4 103 */ 104 105 static void 106 md5_decode(register UINT4* output, register unsigned char* input, unsigned int len) 107 { 108 unsigned int i; 109 unsigned int j; 110 111 for (i = j = 0; j < len; i++, j += 4) 112 output[i] = ((UINT4)input[j]) | 113 (((UINT4)input[j+1]) << 8) | 114 (((UINT4)input[j+2]) << 16) | 115 (((UINT4)input[j+3]) << 24); 116 } 117 118 static int 119 md5_init(Sum_t* p) 120 { 121 register Md5_t* context = (Md5_t*)p; 122 123 context->count[0] = context->count[1] = 0; 124 context->state[0] = 0x67452301; 125 context->state[1] = 0xefcdab89; 126 context->state[2] = 0x98badcfe; 127 context->state[3] = 0x10325476; 128 return 0; 129 } 130 131 static Sum_t* 132 md5_open(const Method_t* method, const char* name) 133 { 134 Md5_t* p; 135 136 if (p = newof(0, Md5_t, 1, 0)) 137 { 138 p->method = (Method_t*)method; 139 p->name = name; 140 md5_init((Sum_t*)p); 141 } 142 return (Sum_t*)p; 143 } 144 145 /* 146 * basic MD5 step -- transforms buf based on in 147 */ 148 149 #define S11 7 150 #define S12 12 151 #define S13 17 152 #define S14 22 153 #define S21 5 154 #define S22 9 155 #define S23 14 156 #define S24 20 157 #define S31 4 158 #define S32 11 159 #define S33 16 160 #define S34 23 161 #define S41 6 162 #define S42 10 163 #define S43 15 164 #define S44 21 165 166 /* F, G, H and I are basic MD5 functions */ 167 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 168 #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 169 #define H(x, y, z) ((x) ^ (y) ^ (z)) 170 #define I(x, y, z) ((y) ^ ((x) | (~z))) 171 172 /* ROTATE_LEFT rotates x left n bits */ 173 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 174 175 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ 176 /* Rotation is separate from addition to prevent recomputation */ 177 #define FF(a, b, c, d, x, s, ac) { \ 178 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 179 (a) = ROTATE_LEFT ((a), (s)); \ 180 (a) += (b); \ 181 } 182 #define GG(a, b, c, d, x, s, ac) { \ 183 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 184 (a) = ROTATE_LEFT ((a), (s)); \ 185 (a) += (b); \ 186 } 187 #define HH(a, b, c, d, x, s, ac) { \ 188 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 189 (a) = ROTATE_LEFT ((a), (s)); \ 190 (a) += (b); \ 191 } 192 #define II(a, b, c, d, x, s, ac) { \ 193 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 194 (a) = ROTATE_LEFT ((a), (s)); \ 195 (a) += (b); \ 196 } 197 198 static void 199 md5_transform(UINT4 state[4], unsigned char block[64]) 200 { 201 UINT4 a = state[0]; 202 UINT4 b = state[1]; 203 UINT4 c = state[2]; 204 UINT4 d = state[3]; 205 UINT4 x[16]; 206 207 md5_decode(x, block, 64); 208 209 /* round 1 */ 210 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ 211 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ 212 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ 213 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ 214 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ 215 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ 216 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ 217 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ 218 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ 219 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ 220 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ 221 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ 222 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ 223 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ 224 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ 225 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ 226 227 /* round 2 */ 228 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ 229 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ 230 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ 231 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ 232 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ 233 GG (d, a, b, c, x[10], S22, 0x02441453); /* 22 */ 234 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ 235 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ 236 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ 237 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ 238 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ 239 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 240 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 241 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 242 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 243 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 244 245 /* round 3 */ 246 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ 247 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ 248 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ 249 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ 250 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ 251 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ 252 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ 253 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ 254 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ 255 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ 256 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ 257 HH (b, c, d, a, x[ 6], S34, 0x04881d05); /* 44 */ 258 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ 259 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ 260 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ 261 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ 262 263 /* round 4 */ 264 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ 265 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ 266 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ 267 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ 268 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ 269 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ 270 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ 271 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ 272 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ 273 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ 274 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ 275 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ 276 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ 277 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ 278 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ 279 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ 280 281 state[0] += a; 282 state[1] += b; 283 state[2] += c; 284 state[3] += d; 285 } 286 287 static int 288 md5_block(Sum_t* p, const void* s, size_t inputLen) 289 { 290 register Md5_t* context = (Md5_t*)p; 291 unsigned char* input = (unsigned char*)s; 292 unsigned int i; 293 unsigned int index; 294 unsigned int partLen; 295 296 /* compute number of bytes mod 64 */ 297 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 298 299 /* update number of bits */ 300 if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) 301 context->count[1]++; 302 context->count[1] += ((UINT4)inputLen >> 29); 303 partLen = 64 - index; 304 305 /* transform as many times as possible */ 306 if (inputLen >= partLen) 307 { 308 memcpy(&context->buffer[index], input, partLen); 309 md5_transform(context->state, context->buffer); 310 for (i = partLen; i + 63 < inputLen; i += 64) 311 md5_transform(context->state, &input[i]); 312 index = 0; 313 } 314 else 315 i = 0; 316 317 /* buffer remaining input */ 318 memcpy(&context->buffer[index], &input[i], inputLen - i); 319 320 return 0; 321 } 322 323 static int 324 md5_done(Sum_t* p) 325 { 326 register Md5_t* context = (Md5_t*)p; 327 unsigned char bits[8]; 328 unsigned int index; 329 unsigned int padLen; 330 331 /* save number of bits */ 332 md5_encode(bits, context->count, sizeof(bits)); 333 334 /* pad out to 56 mod 64 */ 335 index = (unsigned int)((context->count[0] >> 3) & 0x3f); 336 padLen = (index < 56) ? (56 - index) : (120 - index); 337 md5_block(p, md5_pad, padLen); 338 339 /* append length (before padding) */ 340 md5_block(p, bits, sizeof(bits)); 341 342 /* store state in digest */ 343 md5_encode(context->digest, context->state, sizeof(context->digest)); 344 345 /* accumulate the digests */ 346 for (index = 0; index < elementsof(context->digest); index++) 347 context->digest_sum[index] ^= context->digest[index]; 348 349 return 0; 350 } 351 352 static int 353 md5_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale) 354 { 355 register Md5_t* x = (Md5_t*)p; 356 register unsigned char* d; 357 register int n; 358 359 d = (flags & SUM_TOTAL) ? x->digest_sum : x->digest; 360 for (n = 0; n < elementsof(x->digest); n++) 361 sfprintf(sp, "%02x", d[n]); 362 return 0; 363 } 364 365 static int 366 md5_data(Sum_t* p, Sumdata_t* data) 367 { 368 register Md5_t* x = (Md5_t*)p; 369 370 data->size = elementsof(x->digest); 371 data->num = 0; 372 data->buf = x->digest; 373 return 0; 374 } 375