15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The original file was copied from sqlite, and was in the public domain.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code implements the MD5 message-digest algorithm.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The algorithm is due to Ron Rivest.  This code was
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * written by Colin Plumb in 1993, no copyright is claimed.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code is in the public domain; do with it what you wish.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Equivalent code is available from RSA Data Security, Inc.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This code has been tested against that, and is equivalent,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * except that you don't need to include two pages of legalese
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * with every copy.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * To compute the message digest of a chunk of bytes, declare an
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MD5Context structure, pass it to MD5Init, call MD5Update as
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * needed on buffers full of bytes, and then call MD5Final, which
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will fill a supplied 16-byte array with the digest.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/md5.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Context {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 buf[4];
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 bits[2];
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char in[64];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note: this code is harmless on little-endian machines.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void byteReverse(unsigned char *buf, unsigned longs) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32 t;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        do {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ((unsigned)buf[1]<<8 | buf[0]);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                *(uint32 *)buf = t;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                buf += 4;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } while (--longs);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The four core functions - F1 is optimized somewhat */
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define F1(x, y, z) (x & y | ~x & z) */
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define F1(x, y, z) (z ^ (x & (y ^ z)))
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define F2(x, y, z) F1(z, x, y)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define F3(x, y, z) (x ^ y ^ z)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define F4(x, y, z) (y ^ (x | ~z))
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This is the central step in the MD5 algorithm. */
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MD5STEP(f, w, x, y, z, data, s) \
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The core of the MD5 algorithm, this alters an existing MD5 hash to
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reflect the addition of 16 longwords of new data.  MD5Update blocks
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the data and converts bytes into longwords for this routine.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MD5Transform(uint32 buf[4], const uint32 in[16]) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        register uint32 a, b, c, d;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        a = buf[0];
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        b = buf[1];
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = buf[2];
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        d = buf[3];
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buf[0] += a;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buf[1] += b;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buf[2] += c;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        buf[3] += d;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * initialization constants.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MD5Init(MD5Context* context) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        struct Context *ctx = (struct Context *)context;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->buf[0] = 0x67452301;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->buf[1] = 0xefcdab89;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->buf[2] = 0x98badcfe;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->buf[3] = 0x10325476;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->bits[0] = 0;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->bits[1] = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Update context to reflect the concatenation of another buffer full
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of bytes.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MD5Update(MD5Context* context, const StringPiece& data) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const unsigned char* inbuf = (const unsigned char*)data.data();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size_t len = data.size();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        struct Context *ctx = (struct Context *)context;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const unsigned char* buf = (const unsigned char*)inbuf;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uint32 t;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Update bitcount */
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        t = ctx->bits[0];
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ctx->bits[1]++; /* Carry from low to high */
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctx->bits[1] += static_cast<uint32>(len >> 29);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Handle any leading odd-sized chunks */
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (t) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                unsigned char *p = (unsigned char *)ctx->in + t;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                t = 64-t;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (len < t) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        memcpy(p, buf, len);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        return;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                memcpy(p, buf, t);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                byteReverse(ctx->in, 16);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                MD5Transform(ctx->buf, (uint32 *)ctx->in);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                buf += t;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                len -= t;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Process data in 64-byte chunks */
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (len >= 64) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                memcpy(ctx->in, buf, 64);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                byteReverse(ctx->in, 16);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                MD5Transform(ctx->buf, (uint32 *)ctx->in);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                buf += 64;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                len -= 64;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Handle any remaining bytes of data. */
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memcpy(ctx->in, buf, len);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Final wrapup - pad to 64-byte boundary with the bit pattern
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1 0* (64-bit count of bits processed, MSB-first)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MD5Final(MD5Digest* digest, MD5Context* context) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        struct Context *ctx = (struct Context *)context;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned count;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        unsigned char *p;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Compute number of bytes mod 64 */
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count = (ctx->bits[0] >> 3) & 0x3F;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Set the first char of padding to 0x80.  This is safe since there is
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           always at least one byte free */
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        p = ctx->in + count;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *p++ = 0x80;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Bytes of padding needed to make 64 bytes */
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count = 64 - 1 - count;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Pad out to 56 mod 64 */
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (count < 8) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /* Two lots of padding:  Pad the first block to 64 bytes */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                memset(p, 0, count);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                byteReverse(ctx->in, 16);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                MD5Transform(ctx->buf, (uint32 *)ctx->in);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /* Now fill the next block with 56 bytes */
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                memset(ctx->in, 0, 56);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                /* Pad block to 56 bytes */
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                memset(p, 0, count-8);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        byteReverse(ctx->in, 14);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Append length in bits and transform */
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        memcpy(&ctx->in[14 * sizeof(ctx->bits[0])],
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               &ctx->bits[0],
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               sizeof(ctx->bits[0]));
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        memcpy(&ctx->in[15 * sizeof(ctx->bits[1])],
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               &ctx->bits[1],
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)               sizeof(ctx->bits[1]));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MD5Transform(ctx->buf, (uint32 *)ctx->in);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        byteReverse((unsigned char *)ctx->buf, 4);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memcpy(digest->a, ctx->buf, 16);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memset(ctx, 0, sizeof(*ctx));    /* In case it's sensitive */
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
267e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid MD5IntermediateFinal(MD5Digest* digest, const MD5Context* context) {
268e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  /* MD5Final mutates the MD5Context*. Make a copy for generating the
269e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch     intermediate value. */
270e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  MD5Context context_copy;
271e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  memcpy(&context_copy, context, sizeof(context_copy));
272e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  MD5Final(digest, &context_copy);
273e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
274e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MD5DigestToBase16(const MD5Digest& digest) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static char const zEncode[] = "0123456789abcdef";
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string ret;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ret.resize(32);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int j = 0;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 16; i ++) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int a = digest.a[i];
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret[j++] = zEncode[(a>>4)&0xf];
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret[j++] = zEncode[a & 0xf];
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MD5Sum(const void* data, size_t length, MD5Digest* digest) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Context ctx;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Init(&ctx);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Update(&ctx,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            StringPiece(reinterpret_cast<const char*>(data), length));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Final(digest, &ctx);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MD5String(const StringPiece& str) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Digest digest;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Sum(str.data(), str.length(), &digest);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return MD5DigestToBase16(digest);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
305