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 +