|
1 // The original file was copied from sqlite, and was in the public domain. |
|
2 // Modifications Copyright 2006 Google Inc. All Rights Reserved |
|
3 /* |
|
4 * Copyright (C) 2010 Google Inc. All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions are |
|
8 * met: |
|
9 * |
|
10 * * Redistributions of source code must retain the above copyright |
|
11 * notice, this list of conditions and the following disclaimer. |
|
12 * * Redistributions in binary form must reproduce the above |
|
13 * copyright notice, this list of conditions and the following disclaimer |
|
14 * in the documentation and/or other materials provided with the |
|
15 * distribution. |
|
16 * * Neither the name of Google Inc. nor the names of its |
|
17 * contributors may be used to endorse or promote products derived from |
|
18 * this software without specific prior written permission. |
|
19 * |
|
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
31 */ |
|
32 /* |
|
33 * This code implements the MD5 message-digest algorithm. |
|
34 * The algorithm is due to Ron Rivest. This code was |
|
35 * written by Colin Plumb in 1993, no copyright is claimed. |
|
36 * This code is in the public domain; do with it what you wish. |
|
37 * |
|
38 * Equivalent code is available from RSA Data Security, Inc. |
|
39 * This code has been tested against that, and is equivalent, |
|
40 * except that you don't need to include two pages of legalese |
|
41 * with every copy. |
|
42 * |
|
43 * To compute the message digest of a chunk of bytes, construct an |
|
44 * MD5 instance, call addBytes as needed on buffers full of bytes, |
|
45 * and then call checksum, which will fill a supplied 16-byte array |
|
46 * with the digest. |
|
47 */ |
|
48 |
|
49 #include "config.h" |
|
50 #include "MD5.h" |
|
51 |
|
52 #include "Assertions.h" |
|
53 #ifndef NDEBUG |
|
54 #include "StringExtras.h" |
|
55 #include "text/CString.h" |
|
56 #endif |
|
57 |
|
58 namespace WTF { |
|
59 |
|
60 #ifdef NDEBUG |
|
61 static inline void testMD5() { } |
|
62 #else |
|
63 // MD5 test case. |
|
64 static bool isTestMD5Done; |
|
65 |
|
66 static void expectMD5(CString input, CString expected) |
|
67 { |
|
68 MD5 md5; |
|
69 md5.addBytes(reinterpret_cast<const uint8_t*>(input.data()), input.length()); |
|
70 Vector<uint8_t, 16> digest; |
|
71 md5.checksum(digest); |
|
72 char* buf = 0; |
|
73 CString actual = CString::newUninitialized(32, buf); |
|
74 for (size_t i = 0; i < 16; i++) { |
|
75 snprintf(buf, 3, "%02x", digest.at(i)); |
|
76 buf += 2; |
|
77 } |
|
78 ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%d] actual:%s expected:%s", input.data(), input.length(), actual.data(), expected.data()); |
|
79 } |
|
80 |
|
81 static void testMD5() |
|
82 { |
|
83 if (isTestMD5Done) |
|
84 return; |
|
85 isTestMD5Done = true; |
|
86 |
|
87 // MD5 Test suite from http://www.ietf.org/rfc/rfc1321.txt |
|
88 expectMD5("", "d41d8cd98f00b204e9800998ecf8427e"); |
|
89 expectMD5("a", "0cc175b9c0f1b6a831c399e269772661"); |
|
90 expectMD5("abc", "900150983cd24fb0d6963f7d28e17f72"); |
|
91 expectMD5("message digest", "f96b697d7cb7938d525a2f31aaf161d0"); |
|
92 expectMD5("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b"); |
|
93 expectMD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f"); |
|
94 expectMD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a"); |
|
95 } |
|
96 #endif |
|
97 |
|
98 // Note: this code is harmless on little-endian machines. |
|
99 |
|
100 static void reverseBytes(uint8_t* buf, unsigned longs) |
|
101 { |
|
102 ASSERT(longs > 0); |
|
103 do { |
|
104 uint32_t t = static_cast<uint32_t>(buf[3] << 8 | buf[2]) << 16 | buf[1] << 8 | buf[0]; |
|
105 ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(buf) % sizeof(t)), "alignment error of buf"); |
|
106 *reinterpret_cast<uint32_t *>(buf) = t; |
|
107 buf += 4; |
|
108 } while (--longs); |
|
109 } |
|
110 |
|
111 // The four core functions. |
|
112 // F1 is originally defined as (x & y | ~x & z), but optimized somewhat: 4 bit ops -> 3 bit ops. |
|
113 #define F1(x, y, z) (z ^ (x & (y ^ z))) |
|
114 #define F2(x, y, z) F1(z, x, y) |
|
115 #define F3(x, y, z) (x ^ y ^ z) |
|
116 #define F4(x, y, z) (y ^ (x | ~z)) |
|
117 |
|
118 // This is the central step in the MD5 algorithm. |
|
119 #define MD5STEP(f, w, x, y, z, data, s) \ |
|
120 (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) |
|
121 |
|
122 static void MD5Transform(uint32_t buf[4], const uint32_t in[16]) |
|
123 { |
|
124 uint32_t a = buf[0]; |
|
125 uint32_t b = buf[1]; |
|
126 uint32_t c = buf[2]; |
|
127 uint32_t d = buf[3]; |
|
128 |
|
129 MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); |
|
130 MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); |
|
131 MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); |
|
132 MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); |
|
133 MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); |
|
134 MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); |
|
135 MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); |
|
136 MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); |
|
137 MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); |
|
138 MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); |
|
139 MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); |
|
140 MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); |
|
141 MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); |
|
142 MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); |
|
143 MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); |
|
144 MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); |
|
145 |
|
146 MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); |
|
147 MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); |
|
148 MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); |
|
149 MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); |
|
150 MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); |
|
151 MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); |
|
152 MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); |
|
153 MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); |
|
154 MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); |
|
155 MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); |
|
156 MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); |
|
157 MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); |
|
158 MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); |
|
159 MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); |
|
160 MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); |
|
161 MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); |
|
162 |
|
163 MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); |
|
164 MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); |
|
165 MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); |
|
166 MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); |
|
167 MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); |
|
168 MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); |
|
169 MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); |
|
170 MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); |
|
171 MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); |
|
172 MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); |
|
173 MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); |
|
174 MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); |
|
175 MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); |
|
176 MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); |
|
177 MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); |
|
178 MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); |
|
179 |
|
180 MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); |
|
181 MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); |
|
182 MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); |
|
183 MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); |
|
184 MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); |
|
185 MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); |
|
186 MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); |
|
187 MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); |
|
188 MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); |
|
189 MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); |
|
190 MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); |
|
191 MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); |
|
192 MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); |
|
193 MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); |
|
194 MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); |
|
195 MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); |
|
196 |
|
197 buf[0] += a; |
|
198 buf[1] += b; |
|
199 buf[2] += c; |
|
200 buf[3] += d; |
|
201 } |
|
202 |
|
203 MD5::MD5() |
|
204 { |
|
205 testMD5(); |
|
206 m_buf[0] = 0x67452301; |
|
207 m_buf[1] = 0xefcdab89; |
|
208 m_buf[2] = 0x98badcfe; |
|
209 m_buf[3] = 0x10325476; |
|
210 m_bits[0] = 0; |
|
211 m_bits[1] = 0; |
|
212 memset(m_in, 0, sizeof(m_in)); |
|
213 ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(m_in) % sizeof(uint32_t)), "alignment error of m_in"); |
|
214 } |
|
215 |
|
216 void MD5::addBytes(const uint8_t* input, size_t length) |
|
217 { |
|
218 const uint8_t* buf = input; |
|
219 |
|
220 // Update bitcount |
|
221 uint32_t t = m_bits[0]; |
|
222 m_bits[0] = t + (length << 3); |
|
223 if (m_bits[0] < t) |
|
224 m_bits[1]++; // Carry from low to high |
|
225 m_bits[1] += length >> 29; |
|
226 |
|
227 t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data |
|
228 |
|
229 // Handle any leading odd-sized chunks |
|
230 |
|
231 if (t) { |
|
232 uint8_t* p = m_in + t; |
|
233 |
|
234 t = 64 - t; |
|
235 if (length < t) { |
|
236 memcpy(p, buf, length); |
|
237 return; |
|
238 } |
|
239 memcpy(p, buf, t); |
|
240 reverseBytes(m_in, 16); |
|
241 MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); // m_in is 4-byte aligned. |
|
242 buf += t; |
|
243 length -= t; |
|
244 } |
|
245 |
|
246 // Process data in 64-byte chunks |
|
247 |
|
248 while (length >= 64) { |
|
249 memcpy(m_in, buf, 64); |
|
250 reverseBytes(m_in, 16); |
|
251 MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); // m_in is 4-byte aligned. |
|
252 buf += 64; |
|
253 length -= 64; |
|
254 } |
|
255 |
|
256 // Handle any remaining bytes of data. |
|
257 memcpy(m_in, buf, length); |
|
258 } |
|
259 |
|
260 void MD5::checksum(Vector<uint8_t, 16>& digest) |
|
261 { |
|
262 // Compute number of bytes mod 64 |
|
263 unsigned count = (m_bits[0] >> 3) & 0x3F; |
|
264 |
|
265 // Set the first char of padding to 0x80. This is safe since there is |
|
266 // always at least one byte free |
|
267 uint8_t* p = m_in + count; |
|
268 *p++ = 0x80; |
|
269 |
|
270 // Bytes of padding needed to make 64 bytes |
|
271 count = 64 - 1 - count; |
|
272 |
|
273 // Pad out to 56 mod 64 |
|
274 if (count < 8) { |
|
275 // Two lots of padding: Pad the first block to 64 bytes |
|
276 memset(p, 0, count); |
|
277 reverseBytes(m_in, 16); |
|
278 MD5Transform(m_buf, reinterpret_cast<uint32_t *>(m_in)); // m_in is 4-byte aligned. |
|
279 |
|
280 // Now fill the next block with 56 bytes |
|
281 memset(m_in, 0, 56); |
|
282 } else { |
|
283 // Pad block to 56 bytes |
|
284 memset(p, 0, count - 8); |
|
285 } |
|
286 reverseBytes(m_in, 14); |
|
287 |
|
288 // Append length in bits and transform |
|
289 // m_in is 4-byte aligned. |
|
290 (reinterpret_cast<uint32_t*>(m_in))[14] = m_bits[0]; |
|
291 (reinterpret_cast<uint32_t*>(m_in))[15] = m_bits[1]; |
|
292 |
|
293 MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); |
|
294 reverseBytes(reinterpret_cast<uint8_t*>(m_buf), 4); |
|
295 |
|
296 // Now, m_buf contains checksum result. |
|
297 if (!digest.isEmpty()) |
|
298 digest.clear(); |
|
299 digest.append(reinterpret_cast<uint8_t*>(m_buf), 16); |
|
300 |
|
301 // In case it's sensitive |
|
302 memset(m_buf, 0, sizeof(m_buf)); |
|
303 memset(m_bits, 0, sizeof(m_bits)); |
|
304 memset(m_in, 0, sizeof(m_in)); |
|
305 } |
|
306 |
|
307 } // namespace WTF |