/*
 * This code implements the MD5 message-digest algorithm.
 * The algorithm is due to Ron Rivest.  This code was
 * written by Colin Plumb in 1993, no copyright is claimed.
 * This code is in the public domain; do with it what you wish.
 *
 * Equivalent code is available from RSA Data Security, Inc.
 * This code has been tested against that, and is equivalent,
 * except that you don't need to include two pages of legalese
 * with every copy.
 *
 * To compute the message digest of a chunk of bytes, declare an
 * MD5Context structure, pass it to MD5Init, call MD5Update as
 * needed on buffers full of bytes, and then call MD5Final, which
 * will fill a supplied 16-byte array with the digest.
 */

// Changes from original C code:
// Ported to C++, type casting, Google code style.

#include "webrtc/base/md5.h"

// TODO: Avoid memcmpy - hash directly from memory.
#include <string.h>  // for memcpy().

#include "webrtc/base/byteorder.h"  // for RTC_ARCH_CPU_LITTLE_ENDIAN.

namespace rtc {

#ifdef RTC_ARCH_CPU_LITTLE_ENDIAN
#define ByteReverse(buf, len)  // Nothing.
#else  // RTC_ARCH_CPU_BIG_ENDIAN
static void ByteReverse(uint32* buf, int len) {
  for (int i = 0; i < len; ++i) {
    buf[i] = rtc::GetLE32(&buf[i]);
  }
}
#endif

// Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
// initialization constants.
void MD5Init(MD5Context* ctx) {
  ctx->buf[0] = 0x67452301;
  ctx->buf[1] = 0xefcdab89;
  ctx->buf[2] = 0x98badcfe;
  ctx->buf[3] = 0x10325476;
  ctx->bits[0] = 0;
  ctx->bits[1] = 0;
}

// Update context to reflect the concatenation of another buffer full of bytes.
void MD5Update(MD5Context* ctx, const uint8* buf, size_t len) {
  // Update bitcount.
  uint32 t = ctx->bits[0];
  if ((ctx->bits[0] = t + (static_cast<uint32>(len) << 3)) < t) {
    ctx->bits[1]++;  // Carry from low to high.
  }
  ctx->bits[1] += static_cast<uint32>(len >> 29);
  t = (t >> 3) & 0x3f;  // Bytes already in shsInfo->data.

  // Handle any leading odd-sized chunks.
  if (t) {
    uint8* p = reinterpret_cast<uint8*>(ctx->in) + t;

    t = 64-t;
    if (len < t) {
      memcpy(p, buf, len);
      return;
    }
    memcpy(p, buf, t);
    ByteReverse(ctx->in, 16);
    MD5Transform(ctx->buf, ctx->in);
    buf += t;
    len -= t;
  }

  // Process data in 64-byte chunks.
  while (len >= 64) {
    memcpy(ctx->in, buf, 64);
    ByteReverse(ctx->in, 16);
    MD5Transform(ctx->buf, ctx->in);
    buf += 64;
    len -= 64;
  }

  // Handle any remaining bytes of data.
  memcpy(ctx->in, buf, len);
}

// Final wrapup - pad to 64-byte boundary with the bit pattern.
// 1 0* (64-bit count of bits processed, MSB-first)
void MD5Final(MD5Context* ctx, uint8 digest[16]) {
  // Compute number of bytes mod 64.
  uint32 count = (ctx->bits[0] >> 3) & 0x3F;

  // Set the first char of padding to 0x80.  This is safe since there is
  // always at least one byte free.
  uint8* p = reinterpret_cast<uint8*>(ctx->in) + count;
  *p++ = 0x80;

  // Bytes of padding needed to make 64 bytes.
  count = 64 - 1 - count;

  // Pad out to 56 mod 64.
  if (count < 8) {
    // Two lots of padding:  Pad the first block to 64 bytes.
    memset(p, 0, count);
    ByteReverse(ctx->in, 16);
    MD5Transform(ctx->buf, ctx->in);

    // Now fill the next block with 56 bytes.
    memset(ctx->in, 0, 56);
  } else {
    // Pad block to 56 bytes.
    memset(p, 0, count - 8);
  }
  ByteReverse(ctx->in, 14);

  // Append length in bits and transform.
  ctx->in[14] = ctx->bits[0];
  ctx->in[15] = ctx->bits[1];

  MD5Transform(ctx->buf, ctx->in);
  ByteReverse(ctx->buf, 4);
  memcpy(digest, ctx->buf, 16);
  memset(ctx, 0, sizeof(*ctx));  // In case it's sensitive.
}

// The four core functions - F1 is optimized somewhat.
// #define F1(x, y, z) (x & y | ~x & z)
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

// This is the central step in the MD5 algorithm.
#define MD5STEP(f, w, x, y, z, data, s) \
    (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)

// The core of the MD5 algorithm, this alters an existing MD5 hash to
// reflect the addition of 16 longwords of new data.  MD5Update blocks
// the data and converts bytes into longwords for this routine.
void MD5Transform(uint32 buf[4], const uint32 in[16]) {
  uint32 a = buf[0];
  uint32 b = buf[1];
  uint32 c = buf[2];
  uint32 d = buf[3];

  MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);
  MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);
  MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);
  MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);
  MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);
  MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);
  MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);
  MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);
  MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);
  MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);
  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);

  MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);
  MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);
  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);
  MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);
  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);
  MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);
  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);
  MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);
  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);
  MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);
  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);

  MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);
  MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);
  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);
  MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);
  MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);
  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);
  MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);
  MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);
  MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);
  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23);

  MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);
  MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10);
  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21);
  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10);
  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21);
  MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f, 6);
  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15);
  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82, 6);
  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15);
  MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21);
  buf[0] += a;
  buf[1] += b;
  buf[2] += c;
  buf[3] += d;
}

}  // namespace rtc
