/* MD5 block update operation. Continues an MD5 message-digest * operation, processing another message block, and updating the * context. */ private static void MD5Update(MD5_CTX *context, byte *input, uint inputLen) { /* Compute number of bytes mod 64 */ var index = (context->count[0] >> 3) & 0x3F; /* Update number of bits */ if ((context->count[0] += (inputLen << 3)) < (inputLen << 3)) { context->count[1]++; } context->count[1] += (inputLen >> 29); uint partLen = 64 - index; /* Transform as many times as possible. */ uint i = 0; if (inputLen >= partLen) { Buffer.BlockCopy(input, context->buffer + index, partLen); MD5Transform(context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) { MD5Transform(context->state, input + i); } index = 0; } /* Buffer remaining input */ Buffer.BlockCopy(input + i, context->buffer + index, inputLen - i); }
/* MD5 initialization. Begins an MD5 operation, writing a new context. */ private static void MD5Init(MD5_CTX *context) /* context */ { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; }
/* MD5 finalization. Ends an MD5 message-digest operation, writing the * the message digest and zeroizing the context. */ private static void MD5Final(byte *digest, MD5_CTX *context) { var bits = stackalloc byte[8]; /* Save number of bits */ Encode(bits, context->count, 8); /* Pad out to 56 mod 64. */ uint index = (context->count[0] >> 3) & 0x3f; uint padLen = (index < 56) ? (56 - index) : (120 - index); fixed(byte *padding = PADDING) MD5Update(context, padding, padLen); /* Append length (before padding) */ MD5Update(context, bits, 8); /* Store state in digest */ Encode(digest, context->state, 16); /* Zeroize sensitive information. */ context->Clear(); }