toolkit/crashreporter/google-breakpad/src/common/md5.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/md5.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,251 @@
     1.4 +/*
     1.5 + * written by Colin Plumb in 1993, no copyright is claimed.
     1.6 + * This code is in the public domain; do with it what you wish.
     1.7 + *
     1.8 + * Equivalent code is available from RSA Data Security, Inc.
     1.9 + * This code has been tested against that, and is equivalent,
    1.10 + * except that you don't need to include two pages of legalese
    1.11 + * with every copy.
    1.12 + *
    1.13 + * To compute the message digest of a chunk of bytes, declare an
    1.14 + * MD5Context structure, pass it to MD5Init, call MD5Update as
    1.15 + * needed on buffers full of bytes, and then call MD5Final, which
    1.16 + * will fill a supplied 16-byte array with the digest.
    1.17 + */
    1.18 +
    1.19 +#include <string.h>
    1.20 +
    1.21 +#include "common/md5.h"
    1.22 +
    1.23 +namespace google_breakpad {
    1.24 +
    1.25 +#ifndef WORDS_BIGENDIAN
    1.26 +#define byteReverse(buf, len)   /* Nothing */
    1.27 +#else
    1.28 +/*
    1.29 + * Note: this code is harmless on little-endian machines.
    1.30 + */
    1.31 +static void byteReverse(unsigned char *buf, unsigned longs)
    1.32 +{
    1.33 +  u32 t;
    1.34 +  do {
    1.35 +    t = (u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
    1.36 +      ((unsigned) buf[1] << 8 | buf[0]);
    1.37 +    *(u32 *) buf = t;
    1.38 +    buf += 4;
    1.39 +  } while (--longs);
    1.40 +}
    1.41 +#endif
    1.42 +
    1.43 +static void MD5Transform(u32 buf[4], u32 const in[16]);
    1.44 +
    1.45 +/*
    1.46 + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
    1.47 + * initialization constants.
    1.48 + */
    1.49 +void MD5Init(struct MD5Context *ctx)
    1.50 +{
    1.51 +  ctx->buf[0] = 0x67452301;
    1.52 +  ctx->buf[1] = 0xefcdab89;
    1.53 +  ctx->buf[2] = 0x98badcfe;
    1.54 +  ctx->buf[3] = 0x10325476;
    1.55 +
    1.56 +  ctx->bits[0] = 0;
    1.57 +  ctx->bits[1] = 0;
    1.58 +}
    1.59 +
    1.60 +/*
    1.61 + * Update context to reflect the concatenation of another buffer full
    1.62 + * of bytes.
    1.63 + */
    1.64 +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
    1.65 +{
    1.66 +  u32 t;
    1.67 +
    1.68 +  /* Update bitcount */
    1.69 +
    1.70 +  t = ctx->bits[0];
    1.71 +  if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
    1.72 +    ctx->bits[1]++;         /* Carry from low to high */
    1.73 +  ctx->bits[1] += len >> 29;
    1.74 +
    1.75 +  t = (t >> 3) & 0x3f;        /* Bytes already in shsInfo->data */
    1.76 +
    1.77 +  /* Handle any leading odd-sized chunks */
    1.78 +
    1.79 +  if (t) {
    1.80 +    unsigned char *p = (unsigned char *) ctx->in + t;
    1.81 +
    1.82 +    t = 64 - t;
    1.83 +    if (len < t) {
    1.84 +      memcpy(p, buf, len);
    1.85 +      return;
    1.86 +    }
    1.87 +    memcpy(p, buf, t);
    1.88 +    byteReverse(ctx->in, 16);
    1.89 +    MD5Transform(ctx->buf, (u32 *) ctx->in);
    1.90 +    buf += t;
    1.91 +    len -= t;
    1.92 +  }
    1.93 +  /* Process data in 64-byte chunks */
    1.94 +
    1.95 +  while (len >= 64) {
    1.96 +    memcpy(ctx->in, buf, 64);
    1.97 +    byteReverse(ctx->in, 16);
    1.98 +    MD5Transform(ctx->buf, (u32 *) ctx->in);
    1.99 +    buf += 64;
   1.100 +    len -= 64;
   1.101 +  }
   1.102 +
   1.103 +  /* Handle any remaining bytes of data. */
   1.104 +
   1.105 +  memcpy(ctx->in, buf, len);
   1.106 +}
   1.107 +
   1.108 +/*
   1.109 + * Final wrapup - pad to 64-byte boundary with the bit pattern
   1.110 + * 1 0* (64-bit count of bits processed, MSB-first)
   1.111 + */
   1.112 +void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
   1.113 +{
   1.114 +  unsigned count;
   1.115 +  unsigned char *p;
   1.116 +
   1.117 +  /* Compute number of bytes mod 64 */
   1.118 +  count = (ctx->bits[0] >> 3) & 0x3F;
   1.119 +
   1.120 +  /* Set the first char of padding to 0x80.  This is safe since there is
   1.121 +     always at least one byte free */
   1.122 +  p = ctx->in + count;
   1.123 +  *p++ = 0x80;
   1.124 +
   1.125 +  /* Bytes of padding needed to make 64 bytes */
   1.126 +  count = 64 - 1 - count;
   1.127 +
   1.128 +  /* Pad out to 56 mod 64 */
   1.129 +  if (count < 8) {
   1.130 +    /* Two lots of padding:  Pad the first block to 64 bytes */
   1.131 +    memset(p, 0, count);
   1.132 +    byteReverse(ctx->in, 16);
   1.133 +    MD5Transform(ctx->buf, (u32 *) ctx->in);
   1.134 +
   1.135 +    /* Now fill the next block with 56 bytes */
   1.136 +    memset(ctx->in, 0, 56);
   1.137 +  } else {
   1.138 +    /* Pad block to 56 bytes */
   1.139 +    memset(p, 0, count - 8);
   1.140 +  }
   1.141 +  byteReverse(ctx->in, 14);
   1.142 +
   1.143 +  /* Append length in bits and transform */
   1.144 +  ((u32 *) ctx->in)[14] = ctx->bits[0];
   1.145 +  ((u32 *) ctx->in)[15] = ctx->bits[1];
   1.146 +
   1.147 +  MD5Transform(ctx->buf, (u32 *) ctx->in);
   1.148 +  byteReverse((unsigned char *) ctx->buf, 4);
   1.149 +  memcpy(digest, ctx->buf, 16);
   1.150 +  memset(ctx, 0, sizeof(*ctx));        /* In case it's sensitive */
   1.151 +}
   1.152 +
   1.153 +/* The four core functions - F1 is optimized somewhat */
   1.154 +
   1.155 +/* #define F1(x, y, z) (x & y | ~x & z) */
   1.156 +#define F1(x, y, z) (z ^ (x & (y ^ z)))
   1.157 +#define F2(x, y, z) F1(z, x, y)
   1.158 +#define F3(x, y, z) (x ^ y ^ z)
   1.159 +#define F4(x, y, z) (y ^ (x | ~z))
   1.160 +
   1.161 +/* This is the central step in the MD5 algorithm. */
   1.162 +#define MD5STEP(f, w, x, y, z, data, s) \
   1.163 +  ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
   1.164 +
   1.165 +/*
   1.166 + * The core of the MD5 algorithm, this alters an existing MD5 hash to
   1.167 + * reflect the addition of 16 longwords of new data.  MD5Update blocks
   1.168 + * the data and converts bytes into longwords for this routine.
   1.169 + */
   1.170 +static void MD5Transform(u32 buf[4], u32 const in[16])
   1.171 +{
   1.172 +  register u32 a, b, c, d;
   1.173 +
   1.174 +  a = buf[0];
   1.175 +  b = buf[1];
   1.176 +  c = buf[2];
   1.177 +  d = buf[3];
   1.178 +
   1.179 +  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
   1.180 +  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
   1.181 +  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
   1.182 +  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
   1.183 +  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
   1.184 +  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
   1.185 +  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
   1.186 +  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
   1.187 +  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
   1.188 +  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
   1.189 +  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
   1.190 +  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
   1.191 +  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
   1.192 +  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
   1.193 +  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
   1.194 +  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
   1.195 +
   1.196 +  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
   1.197 +  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
   1.198 +  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
   1.199 +  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
   1.200 +  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
   1.201 +  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
   1.202 +  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
   1.203 +  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
   1.204 +  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
   1.205 +  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
   1.206 +  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
   1.207 +  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
   1.208 +  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
   1.209 +  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
   1.210 +  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
   1.211 +  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
   1.212 +
   1.213 +  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
   1.214 +  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
   1.215 +  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
   1.216 +  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
   1.217 +  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
   1.218 +  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
   1.219 +  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
   1.220 +  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
   1.221 +  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
   1.222 +  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
   1.223 +  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
   1.224 +  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
   1.225 +  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
   1.226 +  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
   1.227 +  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
   1.228 +  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
   1.229 +
   1.230 +  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
   1.231 +  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
   1.232 +  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
   1.233 +  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
   1.234 +  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
   1.235 +  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
   1.236 +  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
   1.237 +  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
   1.238 +  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
   1.239 +  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
   1.240 +  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
   1.241 +  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
   1.242 +  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
   1.243 +  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
   1.244 +  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
   1.245 +  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
   1.246 +
   1.247 +  buf[0] += a;
   1.248 +  buf[1] += b;
   1.249 +  buf[2] += c;
   1.250 +  buf[3] += d;
   1.251 +}
   1.252 +
   1.253 +}  // namespace google_breakpad
   1.254 +

mercurial