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