1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
28 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
29 * MD5 Message-Digest Algorithm (RFC 1321).
32 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
35 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
37 * This software was written by Alexander Peslyak in 2001. No copyright is
38 * claimed, and the software is hereby placed in the public domain.
39 * In case this attempt to disclaim copyright and place the software in the
40 * public domain is deemed null and void, then the software is
41 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
42 * general public under the following terms:
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted.
47 * There's ABSOLUTELY NO WARRANTY, express or implied.
49 * (This is a heavily cut-down "BSD license".)
51 * This differs from Colin Plumb's older public domain implementation in that
52 * no exactly 32-bit integer data type is required (any 32-bit or wider
53 * unsigned integer data type will do), there's no compile-time endianness
54 * configuration, and the function prototypes match OpenSSL's. No code from
55 * Colin Plumb's implementation has been reused; this comment merely compares
56 * the properties of the two independent implementations.
58 * The primary goals of this implementation are portability and ease of use.
59 * It is meant to be fast, but not as fast as possible. Some known
60 * optimizations are not included to reduce source code size and avoid
61 * compile-time configuration.
72 * The basic MD5 functions.
74 * F and G are optimized compared to their RFC 1321 definitions for
75 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
78 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
79 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
80 #define H(x, y, z) ((x) ^ (y) ^ (z))
81 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
84 * The MD5 transformation for all four rounds.
86 #define STEP(f, a, b, c, d, x, t, s) \
87 (a) += f((b), (c), (d)) + (x) + (t); \
88 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
92 * SET reads 4 input bytes in little-endian byte order and stores them
93 * in a properly aligned word in host byte order.
95 * The check for little-endian architectures that tolerate unaligned
96 * memory accesses is just an optimization. Nothing will break if it
99 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
101 (*(MD5_u32plus *)&ptr[(n) * 4])
107 (MD5_u32plus)ptr[(n) * 4] | \
108 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
109 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
110 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
116 * This processes one or more 64-byte data blocks, but does NOT update
117 * the bit counters. There are no alignment requirements.
119 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
121 const unsigned char *ptr;
122 MD5_u32plus a, b, c, d;
123 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
125 ptr = static_cast<const unsigned char *>(data);
140 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
141 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
142 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
143 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
144 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
145 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
146 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
147 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
148 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
149 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
150 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
151 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
152 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
153 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
154 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
155 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
158 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
159 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
160 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
161 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
162 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
163 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
164 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
165 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
166 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
167 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
168 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
169 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
170 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
171 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
172 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
173 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
176 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
177 STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
178 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
179 STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
180 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
181 STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
182 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
183 STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
184 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
185 STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
186 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
187 STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
188 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
189 STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
190 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
191 STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
194 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
195 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
196 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
197 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
198 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
199 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
200 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
201 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
202 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
203 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
204 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
205 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
206 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
207 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
208 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
209 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
217 } while (size -= 64);
227 void MD5_Init(MD5_CTX *ctx)
238 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
240 MD5_u32plus saved_lo;
241 unsigned long used, free;
244 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
246 ctx->hi += size >> 29;
248 used = saved_lo & 0x3f;
256 memcpy(&ctx->buffer[used], data, size);
260 memcpy(&ctx->buffer[used], data, free);
261 data = (unsigned char *)data + free;
263 body(ctx, ctx->buffer, 64);
268 data = body(ctx, data, size & ~(unsigned long)0x3f);
272 memcpy(ctx->buffer, data, size);
275 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
277 unsigned long used, free;
279 used = ctx->lo & 0x3f;
281 ctx->buffer[used++] = 0x80;
287 memset(&ctx->buffer[used], 0, free);
288 body(ctx, ctx->buffer, 64);
293 memset(&ctx->buffer[used], 0, free - 8);
296 ctx->buffer[56] = ctx->lo;
297 ctx->buffer[57] = ctx->lo >> 8;
298 ctx->buffer[58] = ctx->lo >> 16;
299 ctx->buffer[59] = ctx->lo >> 24;
300 ctx->buffer[60] = ctx->hi;
301 ctx->buffer[61] = ctx->hi >> 8;
302 ctx->buffer[62] = ctx->hi >> 16;
303 ctx->buffer[63] = ctx->hi >> 24;
305 body(ctx, ctx->buffer, 64);
308 result[1] = ctx->a >> 8;
309 result[2] = ctx->a >> 16;
310 result[3] = ctx->a >> 24;
312 result[5] = ctx->b >> 8;
313 result[6] = ctx->b >> 16;
314 result[7] = ctx->b >> 24;
316 result[9] = ctx->c >> 8;
317 result[10] = ctx->c >> 16;
318 result[11] = ctx->c >> 24;
320 result[13] = ctx->d >> 8;
321 result[14] = ctx->d >> 16;
322 result[15] = ctx->d >> 24;
324 memset(ctx, 0, sizeof(*ctx));
327 // Result needs to be directly extracted by the caller from ctx.a, ctx.b, etc. and the context is not cleared for perf.
328 void MD5_Final(MD5_CTX *ctx)
330 unsigned long used, free;
332 used = ctx->lo & 0x3f;
334 ctx->buffer[used++] = 0x80;
340 memset(&ctx->buffer[used], 0, free);
341 body(ctx, ctx->buffer, 64);
346 memset(&ctx->buffer[used], 0, free - 8);
349 ctx->buffer[56] = ctx->lo;
350 ctx->buffer[57] = ctx->lo >> 8;
351 ctx->buffer[58] = ctx->lo >> 16;
352 ctx->buffer[59] = ctx->lo >> 24;
353 ctx->buffer[60] = ctx->hi;
354 ctx->buffer[61] = ctx->hi >> 8;
355 ctx->buffer[62] = ctx->hi >> 16;
356 ctx->buffer[63] = ctx->hi >> 24;
358 body(ctx, ctx->buffer, 64);
365 gen.update("The quick brown fox jumps over the lazy dog");
366 if (gen.finalize() != md5_hash(0x9D7D109E, 0x82B62B37, 0x351DD86B, 0xD619A442))
370 gen.update("The quick brown fox jumps over the lazy dog.");
371 if (gen.finalize() != md5_hash(0xC209D9E4, 0x1CFBD090, 0xADFF68A0, 0xD0CB22DF))
375 gen.update("This is a test");
376 if (gen.finalize() != md5_hash("ce114e4501d2f4e2dcea3e17b546f339"))
381 if (gen.finalize() != md5_hash("7fc56270e7a70fa81a5935b72eacbe29"))
384 if (gen.finalize() != md5_hash("b86fc6b051f63d73de262d4c34e3a0a9"))
387 if (gen.finalize() != md5_hash("902fbdd2b1df0c4f70b4a5d23525e932"))
391 gen.finalize().get_string(str);
392 if (str != "902fbdd2b1df0c4f70b4a5d23525e932")
396 if (gen.finalize() != md5_hash("d41d8cd98f00b204e9800998ecf8427e"))
398 if (!(gen.finalize() == md5_hash("d41d8cd98f00b204e9800998ecf8427e")))
400 if (gen.finalize() < md5_hash("d41d8cd98f00b204e9800998ecf8427e"))
403 if (md5_hash_gen("fadsahfuidsyuifeywiurhwekjlrhblekwjhbrkjewqhrkjhewrf89ds7f987dsa897dsf9gyuierhlgkjhrekjthnrkejlthoruioguopdsifuapofsdj'fjdsaklhgkdjslfhgjkdfsgfdhjogiuyfviubygvvcx876bv87xcz6vcxyvcxyhkjv").finalize() != md5_hash("8897731974459964203eeee0851d1ef4"))
406 // purposely should fail
407 if (!(md5_hash_gen("Xfadsahfuidsyuifeywiurhwekjlrhblekwjhbrkjewqhrkjhewrf89ds7f987dsa897dsf9gyuierhlgkjhrekjthnrkejlthoruioguopdsifuapofsdj'fjdsaklhgkdjslfhgjkdfsgfdhjogiuyfviubygvvcx876bv87xcz6vcxyvcxyhkjv").finalize() != md5_hash("8897731974459964203eeee0851d1ef4")))
410 if (md5_hash_gen("oidui09ds87f87cfudshufhdsfhkdjhfvu9icxyv789cx67v86dsf87ytiudshfiuhgkjrgwekjhreiour098dsu890f7d897f0ds7g8cydoivhckjhbvkjcvxh98v7by896fs785ds86f586tiy342ugr5iug432rdskhfdsiovioxcuyf890sd78fd78sayuhejhrjkehkjhsdjkfndsjvhd89cv7y8c7x96v78d68f76ds78f6ds78f89sd7f8ds7f98ds7087ds896guicxyviuyxhciuvhyxchvkjcxhkvjhcxuiysdfuifg").finalize() != md5_hash("9d641c30f6755515f6d98258cfc1b300"))