1/* 2 MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm 3 */ 4 5/* 6 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All 7 rights reserved. 8 9 License to copy and use this software is granted provided that it 10 is identified as the "RSA Data Security, Inc. MD5 Message-Digest 11 Algorithm" in all material mentioning or referencing this software 12 or this function. 13 14 License is also granted to make and use derivative works provided 15 that such works are identified as "derived from the RSA Data 16 Security, Inc. MD5 Message-Digest Algorithm" in all material 17 mentioning or referencing the derived work. 18 19 RSA Data Security, Inc. makes no representations concerning either 20 the merchantability of this software or the suitability of this 21 software for any particular purpose. It is provided "as is" 22 without express or implied warranty of any kind. 23 24 These notices must be retained in any copies of any part of this 25 documentation and/or software. 26 27 */ 28 29#include "global.h" 30#include "md5.h" 31 32/* 33 Constants for MD5Transform routine. 34 */ 35#define S11 7 36#define S12 12 37#define S13 17 38#define S14 22 39#define S21 5 40#define S22 9 41#define S23 14 42#define S24 20 43#define S31 4 44#define S32 11 45#define S33 16 46#define S34 23 47#define S41 6 48#define S42 10 49#define S43 15 50#define S44 21 51 52static void MD5Transform PROTO_LIST( ( UINT4[4], 53 unsigned char[64] ) ); 54static void Encode PROTO_LIST( ( unsigned char *, 55 UINT4 *, 56 unsigned int ) ); 57 58static void Decode PROTO_LIST( ( UINT4 *, 59 unsigned char *, 60 unsigned int ) ); 61 62static void MD5_memcpy PROTO_LIST( ( POINTER, 63 POINTER, 64 unsigned int ) ); 65static void MD5_memset PROTO_LIST( ( POINTER, 66 int, 67 unsigned int ) ); 68 69static unsigned char PADDING[64] = { 70 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 73}; 74 75/* 76 F, G, H and I are basic MD5 functions. 77 */ 78#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 79#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) 80#define H(x, y, z) ((x) ^ (y) ^ (z)) 81#define I(x, y, z) ((y) ^ ((x) | (~z))) 82 83/* 84 ROTATE_LEFT rotates x left n bits. 85 */ 86#define ROTATE_LEFT(x, n) (((x) <<(n)) | ((x) >> (32-(n)))) 87 88/* 89 FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. 90 Rotation is separate from addition to prevent recomputation. 91 */ 92#define FF(a, b, c, d, x, s, ac) { \ 93 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ 94 (a) = ROTATE_LEFT ((a), (s)); \ 95 (a) += (b); \ 96 } 97 98#define GG(a, b, c, d, x, s, ac) { \ 99 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ 100 (a) = ROTATE_LEFT ((a), (s)); \ 101 (a) += (b); \ 102 } 103 104#define HH(a, b, c, d, x, s, ac) { \ 105 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ 106 (a) = ROTATE_LEFT ((a), (s)); \ 107 (a) += (b); \ 108 } 109 110#define II(a, b, c, d, x, s, ac) { \ 111 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ 112 (a) = ROTATE_LEFT ((a), (s)); \ 113 (a) += (b); \ 114 } 115 116/* 117 MD5 initialization. Begins an MD5 operation, writing a new context. 118 */ 119void 120MD5Init( context ) 121 MD5_CTX *context; /* context */ 122{ 123 context->count[0] = context->count[1] = 0; 124 125 /* 126 Load magic initialization constants. 127 */ 128 context->state[0] = 0x67452301; 129 context->state[1] = 0xefcdab89; 130 context->state[2] = 0x98badcfe; 131 context->state[3] = 0x10325476; 132} 133 134/* 135 MD5 block update operation. Continues an MD5 message-digest 136 operation, processing another message block, and updating the 137 context. 138 */ 139 140void 141MD5Update( context, 142 input, 143 inputLen ) 144 MD5_CTX *context; /* context */ 145 unsigned char *input; /* input block */ 146 unsigned int inputLen; /* length of input block */ 147{ 148 unsigned int i, 149 index_1, 150 partLen; 151 152 /* 153 Compute number of bytes mod 64 154 */ 155 index_1 = ( unsigned int )( ( context->count[0] >> 3 ) & 0x3F ); 156 157 /* 158 Update number of bits 159 */ 160 if( ( context->count[0] += 161 ( ( UINT4 ) inputLen << 3 ) ) < ( ( UINT4 ) inputLen << 3 ) ) 162 context->count[1]++; 163 164 context->count[1] += ( ( UINT4 ) inputLen >> 29 ); 165 166 partLen = 64 - index_1; 167 168 /* 169 Transform as many times as possible. 170 */ 171 if( inputLen >= partLen ) { 172 173 MD5_memcpy 174 ( ( POINTER ) & context->buffer[index_1], ( POINTER ) input, 175 partLen ); 176 MD5Transform( context->state, context->buffer ); 177 178 for( i = partLen; i + 63 < inputLen; i += 64 ) 179 MD5Transform( context->state, &input[i] ); 180 181 index_1 = 0; 182 } else 183 i = 0; 184 185 /* 186 Buffer remaining input 187 */ 188 MD5_memcpy 189 ( ( POINTER ) & context->buffer[index_1], ( POINTER ) & input[i], 190 inputLen - i ); 191 192} 193 194/* 195 MD5 finalization. Ends an MD5 message-digest operation, writing the 196 the message digest and zeroizing the context. 197 */ 198 199void 200MD5Final( digest, 201 context ) 202 unsigned char digest[16]; /* message digest */ 203 MD5_CTX *context; /* context */ 204{ 205 206 unsigned char bits[8]; 207 unsigned int index_1, 208 padLen; 209 210 /* 211 Save number of bits 212 */ 213 Encode( bits, context->count, 8 ); 214 215 /* 216 Pad out to 56 mod 64. 217 */ 218 index_1 = ( unsigned int )( ( context->count[0] >> 3 ) & 0x3f ); 219 220 padLen = ( index_1 < 56 ) ? ( 56 - index_1 ) : ( 120 - index_1 ); 221 222 MD5Update( context, PADDING, padLen ); 223 224 /* 225 Append length (before padding) 226 */ 227 MD5Update( context, bits, 8 ); 228 229 /* 230 Store state in digest 231 */ 232 Encode( digest, context->state, 16 ); 233 234 /* 235 Zeroize sensitive information. 236 */ 237 MD5_memset( ( POINTER ) context, 0, sizeof( *context ) ); 238 239} 240 241/* 242 MD5 basic transformation. Transforms state based on block. 243 */ 244static void 245MD5Transform( state, 246 block ) 247 UINT4 state[4]; 248 unsigned char block[64]; 249{ 250 UINT4 a = state[0], 251 b = state[1], 252 c = state[2], 253 d = state[3], 254 x[16]; 255 256 Decode( x, block, 64 ); 257 258 /* 259 Round 1 260 */ 261 FF( a, b, c, d, x[0], S11, 0xd76aa478 ); /* 1 */ 262 FF( d, a, b, c, x[1], S12, 0xe8c7b756 ); /* 2 */ 263 FF( c, d, a, b, x[2], S13, 0x242070db ); /* 3 */ 264 FF( b, c, d, a, x[3], S14, 0xc1bdceee ); /* 4 */ 265 FF( a, b, c, d, x[4], S11, 0xf57c0faf ); /* 5 */ 266 FF( d, a, b, c, x[5], S12, 0x4787c62a ); /* 6 */ 267 FF( c, d, a, b, x[6], S13, 0xa8304613 ); /* 7 */ 268 FF( b, c, d, a, x[7], S14, 0xfd469501 ); /* 8 */ 269 FF( a, b, c, d, x[8], S11, 0x698098d8 ); /* 9 */ 270 FF( d, a, b, c, x[9], S12, 0x8b44f7af ); /* 10 */ 271 FF( c, d, a, b, x[10], S13, 0xffff5bb1 ); /* 11 */ 272 FF( b, c, d, a, x[11], S14, 0x895cd7be ); /* 12 */ 273 FF( a, b, c, d, x[12], S11, 0x6b901122 ); /* 13 */ 274 FF( d, a, b, c, x[13], S12, 0xfd987193 ); /* 14 */ 275 FF( c, d, a, b, x[14], S13, 0xa679438e ); /* 15 */ 276 FF( b, c, d, a, x[15], S14, 0x49b40821 ); /* 16 */ 277 278 /* 279 Round 2 280 */ 281 GG( a, b, c, d, x[1], S21, 0xf61e2562 ); /* 17 */ 282 GG( d, a, b, c, x[6], S22, 0xc040b340 ); /* 18 */ 283 GG( c, d, a, b, x[11], S23, 0x265e5a51 ); /* 19 */ 284 GG( b, c, d, a, x[0], S24, 0xe9b6c7aa ); /* 20 */ 285 GG( a, b, c, d, x[5], S21, 0xd62f105d ); /* 21 */ 286 GG( d, a, b, c, x[10], S22, 0x2441453 ); /* 22 */ 287 GG( c, d, a, b, x[15], S23, 0xd8a1e681 ); /* 23 */ 288 GG( b, c, d, a, x[4], S24, 0xe7d3fbc8 ); /* 24 */ 289 GG( a, b, c, d, x[9], S21, 0x21e1cde6 ); /* 25 */ 290 GG( d, a, b, c, x[14], S22, 0xc33707d6 ); /* 26 */ 291 GG( c, d, a, b, x[3], S23, 0xf4d50d87 ); /* 27 */ 292 GG( b, c, d, a, x[8], S24, 0x455a14ed ); /* 28 */ 293 GG( a, b, c, d, x[13], S21, 0xa9e3e905 ); /* 29 */ 294 GG( d, a, b, c, x[2], S22, 0xfcefa3f8 ); /* 30 */ 295 GG( c, d, a, b, x[7], S23, 0x676f02d9 ); /* 31 */ 296 GG( b, c, d, a, x[12], S24, 0x8d2a4c8a ); /* 32 */ 297 298 /* 299 Round 3 300 */ 301 HH( a, b, c, d, x[5], S31, 0xfffa3942 ); /* 33 */ 302 HH( d, a, b, c, x[8], S32, 0x8771f681 ); /* 34 */ 303 HH( c, d, a, b, x[11], S33, 0x6d9d6122 ); /* 35 */ 304 HH( b, c, d, a, x[14], S34, 0xfde5380c ); /* 36 */ 305 HH( a, b, c, d, x[1], S31, 0xa4beea44 ); /* 37 */ 306 HH( d, a, b, c, x[4], S32, 0x4bdecfa9 ); /* 38 */ 307 HH( c, d, a, b, x[7], S33, 0xf6bb4b60 ); /* 39 */ 308 HH( b, c, d, a, x[10], S34, 0xbebfbc70 ); /* 40 */ 309 HH( a, b, c, d, x[13], S31, 0x289b7ec6 ); /* 41 */ 310 HH( d, a, b, c, x[0], S32, 0xeaa127fa ); /* 42 */ 311 HH( c, d, a, b, x[3], S33, 0xd4ef3085 ); /* 43 */ 312 HH( b, c, d, a, x[6], S34, 0x4881d05 ); /* 44 */ 313 HH( a, b, c, d, x[9], S31, 0xd9d4d039 ); /* 45 */ 314 HH( d, a, b, c, x[12], S32, 0xe6db99e5 ); /* 46 */ 315 HH( c, d, a, b, x[15], S33, 0x1fa27cf8 ); /* 47 */ 316 HH( b, c, d, a, x[2], S34, 0xc4ac5665 ); /* 48 */ 317 318 /* 319 Round 4 320 */ 321 II( a, b, c, d, x[0], S41, 0xf4292244 ); /* 49 */ 322 II( d, a, b, c, x[7], S42, 0x432aff97 ); /* 50 */ 323 II( c, d, a, b, x[14], S43, 0xab9423a7 ); /* 51 */ 324 II( b, c, d, a, x[5], S44, 0xfc93a039 ); /* 52 */ 325 II( a, b, c, d, x[12], S41, 0x655b59c3 ); /* 53 */ 326 II( d, a, b, c, x[3], S42, 0x8f0ccc92 ); /* 54 */ 327 II( c, d, a, b, x[10], S43, 0xffeff47d ); /* 55 */ 328 II( b, c, d, a, x[1], S44, 0x85845dd1 ); /* 56 */ 329 II( a, b, c, d, x[8], S41, 0x6fa87e4f ); /* 57 */ 330 II( d, a, b, c, x[15], S42, 0xfe2ce6e0 ); /* 58 */ 331 II( c, d, a, b, x[6], S43, 0xa3014314 ); /* 59 */ 332 II( b, c, d, a, x[13], S44, 0x4e0811a1 ); /* 60 */ 333 II( a, b, c, d, x[4], S41, 0xf7537e82 ); /* 61 */ 334 II( d, a, b, c, x[11], S42, 0xbd3af235 ); /* 62 */ 335 II( c, d, a, b, x[2], S43, 0x2ad7d2bb ); /* 63 */ 336 II( b, c, d, a, x[9], S44, 0xeb86d391 ); /* 64 */ 337 338 state[0] += a; 339 state[1] += b; 340 state[2] += c; 341 state[3] += d; 342 343 /* 344 Zeroize sensitive information. 345 */ 346 MD5_memset( ( POINTER ) x, 0, sizeof( x ) ); 347 348} 349 350/* 351 Encodes input (UINT4) into output (unsigned char). Assumes len is 352 a multiple of 4. 353 */ 354static void 355Encode( output, 356 input, 357 len ) 358 unsigned char *output; 359 UINT4 *input; 360 unsigned int len; 361{ 362 unsigned int i, 363 j; 364 365 for( i = 0, j = 0; j < len; i++, j += 4 ) { 366 output[j] = ( unsigned char )( input[i] & 0xff ); 367 output[j + 1] = ( unsigned char )( ( input[i] >> 8 ) & 0xff ); 368 output[j + 2] = ( unsigned char )( ( input[i] >> 16 ) & 0xff ); 369 output[j + 3] = ( unsigned char )( ( input[i] >> 24 ) & 0xff ); 370 } 371 372} 373 374/* 375 Decodes input (unsigned char) into output (UINT4). Assumes len is 376 a multiple of 4. 377 */ 378 379static void 380Decode( output, 381 input, 382 len ) 383 UINT4 *output; 384 unsigned char *input; 385 unsigned int len; 386{ 387 unsigned int i, 388 j; 389 390 for( i = 0, j = 0; j < len; i++, j += 4 ) 391 output[i] = 392 ( ( UINT4 ) input[j] ) | ( ( ( UINT4 ) input[j + 1] ) << 8 ) | 393 ( ( ( UINT4 ) input[j + 2] ) << 16 ) | 394 ( ( ( UINT4 ) input[j + 3] ) << 24 ); 395} 396 397/* 398 Note: Replace "for loop" with standard memcpy if possible. 399 */ 400static void 401MD5_memcpy( output, 402 input, 403 len ) 404 POINTER output; 405 POINTER input; 406 unsigned int len; 407{ 408 unsigned int i; 409 410 for( i = 0; i < len; i++ ) 411 output[i] = input[i]; 412 413} 414 415/* 416 Note: Replace "for loop" with standard memset if possible. 417 */ 418static void 419MD5_memset( output, 420 value, 421 len ) 422 POINTER output; 423 int value; 424 unsigned int len; 425{ 426 unsigned int i; 427 428 for( i = 0; i < len; i++ ) 429 ( ( char * )output )[i] = ( char )value; 430 431} 432