1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The original file was copied from sqlite, and was in the public domain. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Modifications Copyright 2006 Google Inc. All Rights Reserved 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * This code implements the MD5 message-digest algorithm. 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * The algorithm is due to Ron Rivest. This code was 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * written by Colin Plumb in 1993, no copyright is claimed. 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * This code is in the public domain; do with it what you wish. 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Equivalent code is available from RSA Data Security, Inc. 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * This code has been tested against that, and is equivalent, 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * except that you don't need to include two pages of legalese 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * with every copy. 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * To compute the message digest of a chunk of bytes, declare an 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * MD5Context structure, pass it to MD5Init, call MD5Update as 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * needed on buffers full of bytes, and then call MD5Final, which 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * will fill a supplied 16-byte array with the digest. 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/md5.h" 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Context { 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 buf[4]; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 bits[2]; 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char in[64]; 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Note: this code is harmless on little-endian machines. 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void byteReverse(unsigned char *buf, unsigned longs){ 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 t; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 | 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ((unsigned)buf[1]<<8 | buf[0]); 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *(uint32 *)buf = t; 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf += 4; 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (--longs); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* The four core functions - F1 is optimized somewhat */ 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* #define F1(x, y, z) (x & y | ~x & z) */ 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define F1(x, y, z) (z ^ (x & (y ^ z))) 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define F2(x, y, z) F1(z, x, y) 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define F3(x, y, z) (x ^ y ^ z) 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define F4(x, y, z) (y ^ (x | ~z)) 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* This is the central step in the MD5 algorithm. */ 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define MD5STEP(f, w, x, y, z, data, s) \ 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * The core of the MD5 algorithm, this alters an existing MD5 hash to 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * reflect the addition of 16 longwords of new data. MD5Update blocks 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the data and converts bytes into longwords for this routine. 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void MD5Transform(uint32 buf[4], const uint32 in[16]){ 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott register uint32 a, b, c, d; 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a = buf[0]; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott b = buf[1]; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott c = buf[2]; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott d = buf[3]; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf[0] += a; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf[1] += b; 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf[2] += c; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf[3] += d; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * initialization constants. 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MD5Init(MD5Context *pCtx){ 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Context *ctx = (struct Context *)pCtx; 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->buf[0] = 0x67452301; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->buf[1] = 0xefcdab89; 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->buf[2] = 0x98badcfe; 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->buf[3] = 0x10325476; 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->bits[0] = 0; 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->bits[1] = 0; 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Update context to reflect the concatenation of another buffer full 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * of bytes. 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MD5Update(MD5Context *pCtx, const void *inbuf, size_t len){ 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Context *ctx = (struct Context *)pCtx; 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const unsigned char* buf = (const unsigned char*)inbuf; 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint32 t; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Update bitcount */ 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott t = ctx->bits[0]; 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ((ctx->bits[0] = t + ((uint32)len << 3)) < t) 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->bits[1]++; /* Carry from low to high */ 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ctx->bits[1] += static_cast<uint32>(len >> 29); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Handle any leading odd-sized chunks */ 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (t) { 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char *p = (unsigned char *)ctx->in + t; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott t = 64-t; 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (len < t) { 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(p, buf, len); 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(p, buf, t); 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott byteReverse(ctx->in, 16); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Transform(ctx->buf, (uint32 *)ctx->in); 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf += t; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott len -= t; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Process data in 64-byte chunks */ 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (len >= 64) { 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(ctx->in, buf, 64); 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott byteReverse(ctx->in, 16); 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Transform(ctx->buf, (uint32 *)ctx->in); 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott buf += 64; 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott len -= 64; 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Handle any remaining bytes of data. */ 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(ctx->in, buf, len); 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Final wrapup - pad to 64-byte boundary with the bit pattern 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1 0* (64-bit count of bits processed, MSB-first) 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */ 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MD5Final(MD5Digest* digest, MD5Context *pCtx){ 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott struct Context *ctx = (struct Context *)pCtx; 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned count; 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned char *p; 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Compute number of bytes mod 64 */ 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott count = (ctx->bits[0] >> 3) & 0x3F; 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Set the first char of padding to 0x80. This is safe since there is 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott always at least one byte free */ 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott p = ctx->in + count; 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *p++ = 0x80; 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Bytes of padding needed to make 64 bytes */ 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott count = 64 - 1 - count; 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Pad out to 56 mod 64 */ 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (count < 8) { 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Two lots of padding: Pad the first block to 64 bytes */ 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(p, 0, count); 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott byteReverse(ctx->in, 16); 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Transform(ctx->buf, (uint32 *)ctx->in); 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Now fill the next block with 56 bytes */ 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(ctx->in, 0, 56); 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Pad block to 56 bytes */ 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(p, 0, count-8); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott byteReverse(ctx->in, 14); 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott /* Append length in bits and transform */ 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0]; 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1]; 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Transform(ctx->buf, (uint32 *)ctx->in); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott byteReverse((unsigned char *)ctx->buf, 4); 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(digest->a, ctx->buf, 16); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string MD5DigestToBase16(const MD5Digest& digest){ 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static char const zEncode[] = "0123456789abcdef"; 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string ret; 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret.resize(32); 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int j = 0; 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < 16; i ++) { 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int a = digest.a[i]; 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret[j++] = zEncode[(a>>4)&0xf]; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ret[j++] = zEncode[a & 0xf]; 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ret; 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MD5Sum(const void* data, size_t length, MD5Digest* digest) { 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Context ctx; 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Init(&ctx); 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Update(&ctx, static_cast<const unsigned char*>(data), length); 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Final(digest, &ctx); 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstd::string MD5String(const std::string& str) { 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Digest digest; 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MD5Sum(str.data(), str.length(), &digest); 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return MD5DigestToBase16(digest); 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 280