blob: 4ad360686913fc9d325e1f883b473e1fb86e8bfd [file] [log] [blame]
Austin Schuh24adb6b2015-09-06 17:37:40 -07001// Copyright (c) 2013, Matt Godbolt
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// Redistributions of source code must retain the above copyright notice, this
8// list of conditions and the following disclaimer.
9//
10// Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24// POSSIBILITY OF SUCH DAMAGE.
25
26/*
27 Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
28
29 This software is provided 'as-is', without any express or implied
30 warranty. In no event will the authors be held liable for any damages
31 arising from the use of this software.
32
33 Permission is granted to anyone to use this software for any purpose,
34 including commercial applications, and to alter it and redistribute it
35 freely, subject to the following restrictions:
36
37 1. The origin of this software must not be misrepresented; you must not
38 claim that you wrote the original software. If you use this software
39 in a product, an acknowledgment in the product documentation would be
40 appreciated but is not required.
41 2. Altered source versions must be plainly marked as such, and must not be
42 misrepresented as being the original software.
43 3. This notice may not be removed or altered from any source distribution.
44
45 L. Peter Deutsch
46 ghost@aladdin.com
47
48 */
49/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
50/*
51 Independent implementation of MD5 (RFC 1321).
52
53 This code implements the MD5 Algorithm defined in RFC 1321, whose
54 text is available at
55 http://www.ietf.org/rfc/rfc1321.txt
56 The code is derived from the text of the RFC, including the test suite
57 (section A.5) but excluding the rest of Appendix A. It does not include
58 any code or documentation that is identified in the RFC as being
59 copyrighted.
60
61 The original and principal author of md5.c is L. Peter Deutsch
62 <ghost@aladdin.com>. Other authors are noted in the change history
63 that follows (in reverse chronological order):
64
65 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
66 either statically or dynamically; added missing #include <string.h>
67 in library.
68 2002-03-11 lpd Corrected argument list for main(), and added int return
69 type, in test program and T value program.
70 2002-02-21 lpd Added missing #include <stdio.h> in test program.
71 2000-07-03 lpd Patched to eliminate warnings about "constant is
72 unsigned in ANSI C, signed in traditional"; made test program
73 self-checking.
74 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
75 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
76 1999-05-03 lpd Original version.
77 */
78
79#include "md5/md5.h"
80
81#include <string.h>
82
83#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
84#ifdef ARCH_IS_BIG_ENDIAN
85# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
86#else
87# define BYTE_ORDER 0
88#endif
89
90#define T_MASK ((md5_word_t)~0)
91#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
92#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
93#define T3 0x242070db
94#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
95#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
96#define T6 0x4787c62a
97#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
98#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
99#define T9 0x698098d8
100#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
101#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
102#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
103#define T13 0x6b901122
104#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
105#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
106#define T16 0x49b40821
107#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
108#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
109#define T19 0x265e5a51
110#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
111#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
112#define T22 0x02441453
113#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
114#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
115#define T25 0x21e1cde6
116#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
117#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
118#define T28 0x455a14ed
119#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
120#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
121#define T31 0x676f02d9
122#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
123#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
124#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
125#define T35 0x6d9d6122
126#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
127#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
128#define T38 0x4bdecfa9
129#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
130#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
131#define T41 0x289b7ec6
132#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
133#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
134#define T44 0x04881d05
135#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
136#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
137#define T47 0x1fa27cf8
138#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
139#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
140#define T50 0x432aff97
141#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
142#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
143#define T53 0x655b59c3
144#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
145#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
146#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
147#define T57 0x6fa87e4f
148#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
149#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
150#define T60 0x4e0811a1
151#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
152#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
153#define T63 0x2ad7d2bb
154#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
155
156
157static void
158md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
159{
160 md5_word_t
161 a = pms->abcd[0], b = pms->abcd[1],
162 c = pms->abcd[2], d = pms->abcd[3];
163 md5_word_t t;
164#if BYTE_ORDER > 0
165 /* Define storage only for big-endian CPUs. */
166 md5_word_t X[16];
167#else
168 /* Define storage for little-endian or both types of CPUs. */
169 md5_word_t xbuf[16];
170 const md5_word_t *X;
171#endif
172
173 {
174#if BYTE_ORDER == 0
175 /*
176 * Determine dynamically whether this is a big-endian or
177 * little-endian machine, since we can use a more efficient
178 * algorithm on the latter.
179 */
180 static const int w = 1;
181
182 if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
183#endif
184#if BYTE_ORDER <= 0 /* little-endian */
185 {
186 /*
187 * On little-endian machines, we can process properly aligned
188 * data without copying it.
189 */
190 if (!((data - (const md5_byte_t *)0) & 3)) {
191 /* data are properly aligned */
192 X = (const md5_word_t *)data;
193 } else {
194 /* not aligned */
195 memcpy(xbuf, data, 64);
196 X = xbuf;
197 }
198 }
199#endif
200#if BYTE_ORDER == 0
201 else /* dynamic big-endian */
202#endif
203#if BYTE_ORDER >= 0 /* big-endian */
204 {
205 /*
206 * On big-endian machines, we must arrange the bytes in the
207 * right order.
208 */
209 const md5_byte_t *xp = data;
210 int i;
211
212# if BYTE_ORDER == 0
213 X = xbuf; /* (dynamic only) */
214# else
215# define xbuf X /* (static only) */
216# endif
217 for (i = 0; i < 16; ++i, xp += 4)
218 xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
219 }
220#endif
221 }
222
223#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
224
225 /* Round 1. */
226 /* Let [abcd k s i] denote the operation
227 a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
228#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
229#define SET(a, b, c, d, k, s, Ti)\
230 t = a + F(b,c,d) + X[k] + Ti;\
231 a = ROTATE_LEFT(t, s) + b
232 /* Do the following 16 operations. */
233 SET(a, b, c, d, 0, 7, T1);
234 SET(d, a, b, c, 1, 12, T2);
235 SET(c, d, a, b, 2, 17, T3);
236 SET(b, c, d, a, 3, 22, T4);
237 SET(a, b, c, d, 4, 7, T5);
238 SET(d, a, b, c, 5, 12, T6);
239 SET(c, d, a, b, 6, 17, T7);
240 SET(b, c, d, a, 7, 22, T8);
241 SET(a, b, c, d, 8, 7, T9);
242 SET(d, a, b, c, 9, 12, T10);
243 SET(c, d, a, b, 10, 17, T11);
244 SET(b, c, d, a, 11, 22, T12);
245 SET(a, b, c, d, 12, 7, T13);
246 SET(d, a, b, c, 13, 12, T14);
247 SET(c, d, a, b, 14, 17, T15);
248 SET(b, c, d, a, 15, 22, T16);
249#undef SET
250
251 /* Round 2. */
252 /* Let [abcd k s i] denote the operation
253 a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
254#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
255#define SET(a, b, c, d, k, s, Ti)\
256 t = a + G(b,c,d) + X[k] + Ti;\
257 a = ROTATE_LEFT(t, s) + b
258 /* Do the following 16 operations. */
259 SET(a, b, c, d, 1, 5, T17);
260 SET(d, a, b, c, 6, 9, T18);
261 SET(c, d, a, b, 11, 14, T19);
262 SET(b, c, d, a, 0, 20, T20);
263 SET(a, b, c, d, 5, 5, T21);
264 SET(d, a, b, c, 10, 9, T22);
265 SET(c, d, a, b, 15, 14, T23);
266 SET(b, c, d, a, 4, 20, T24);
267 SET(a, b, c, d, 9, 5, T25);
268 SET(d, a, b, c, 14, 9, T26);
269 SET(c, d, a, b, 3, 14, T27);
270 SET(b, c, d, a, 8, 20, T28);
271 SET(a, b, c, d, 13, 5, T29);
272 SET(d, a, b, c, 2, 9, T30);
273 SET(c, d, a, b, 7, 14, T31);
274 SET(b, c, d, a, 12, 20, T32);
275#undef SET
276
277 /* Round 3. */
278 /* Let [abcd k s t] denote the operation
279 a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
280#define H(x, y, z) ((x) ^ (y) ^ (z))
281#define SET(a, b, c, d, k, s, Ti)\
282 t = a + H(b,c,d) + X[k] + Ti;\
283 a = ROTATE_LEFT(t, s) + b
284 /* Do the following 16 operations. */
285 SET(a, b, c, d, 5, 4, T33);
286 SET(d, a, b, c, 8, 11, T34);
287 SET(c, d, a, b, 11, 16, T35);
288 SET(b, c, d, a, 14, 23, T36);
289 SET(a, b, c, d, 1, 4, T37);
290 SET(d, a, b, c, 4, 11, T38);
291 SET(c, d, a, b, 7, 16, T39);
292 SET(b, c, d, a, 10, 23, T40);
293 SET(a, b, c, d, 13, 4, T41);
294 SET(d, a, b, c, 0, 11, T42);
295 SET(c, d, a, b, 3, 16, T43);
296 SET(b, c, d, a, 6, 23, T44);
297 SET(a, b, c, d, 9, 4, T45);
298 SET(d, a, b, c, 12, 11, T46);
299 SET(c, d, a, b, 15, 16, T47);
300 SET(b, c, d, a, 2, 23, T48);
301#undef SET
302
303 /* Round 4. */
304 /* Let [abcd k s t] denote the operation
305 a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
306#define I(x, y, z) ((y) ^ ((x) | ~(z)))
307#define SET(a, b, c, d, k, s, Ti)\
308 t = a + I(b,c,d) + X[k] + Ti;\
309 a = ROTATE_LEFT(t, s) + b
310 /* Do the following 16 operations. */
311 SET(a, b, c, d, 0, 6, T49);
312 SET(d, a, b, c, 7, 10, T50);
313 SET(c, d, a, b, 14, 15, T51);
314 SET(b, c, d, a, 5, 21, T52);
315 SET(a, b, c, d, 12, 6, T53);
316 SET(d, a, b, c, 3, 10, T54);
317 SET(c, d, a, b, 10, 15, T55);
318 SET(b, c, d, a, 1, 21, T56);
319 SET(a, b, c, d, 8, 6, T57);
320 SET(d, a, b, c, 15, 10, T58);
321 SET(c, d, a, b, 6, 15, T59);
322 SET(b, c, d, a, 13, 21, T60);
323 SET(a, b, c, d, 4, 6, T61);
324 SET(d, a, b, c, 11, 10, T62);
325 SET(c, d, a, b, 2, 15, T63);
326 SET(b, c, d, a, 9, 21, T64);
327#undef SET
328
329 /* Then perform the following additions. (That is increment each
330 of the four registers by the value it had before this block
331 was started.) */
332 pms->abcd[0] += a;
333 pms->abcd[1] += b;
334 pms->abcd[2] += c;
335 pms->abcd[3] += d;
336}
337
338#ifdef __cplusplus
339extern "C"
340{
341#endif
342
343void
344md5_init(md5_state_t *pms)
345{
346 pms->count[0] = pms->count[1] = 0;
347 pms->abcd[0] = 0x67452301;
348 pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
349 pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
350 pms->abcd[3] = 0x10325476;
351}
352
353void
354md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
355{
356 const md5_byte_t *p = data;
357 int left = nbytes;
358 int offset = (pms->count[0] >> 3) & 63;
359 md5_word_t nbits = (md5_word_t)(nbytes << 3);
360
361 if (nbytes <= 0)
362 return;
363
364 /* Update the message length. */
365 pms->count[1] += nbytes >> 29;
366 pms->count[0] += nbits;
367 if (pms->count[0] < nbits)
368 pms->count[1]++;
369
370 /* Process an initial partial block. */
371 if (offset) {
372 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
373
374 memcpy(pms->buf + offset, p, copy);
375 if (offset + copy < 64)
376 return;
377 p += copy;
378 left -= copy;
379 md5_process(pms, pms->buf);
380 }
381
382 /* Process full blocks. */
383 for (; left >= 64; p += 64, left -= 64)
384 md5_process(pms, p);
385
386 /* Process a final partial block. */
387 if (left)
388 memcpy(pms->buf, p, left);
389}
390
391void
392md5_finish(md5_state_t *pms, md5_byte_t digest[16])
393{
394 static const md5_byte_t pad[64] = {
395 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
399 };
400 md5_byte_t data[8];
401 int i;
402
403 /* Save the length before padding. */
404 for (i = 0; i < 8; ++i)
405 data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
406 /* Pad to 56 bytes mod 64. */
407 md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
408 /* Append the length. */
409 md5_append(pms, data, 8);
410 for (i = 0; i < 16; ++i)
411 digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
412}
413
414#ifdef __cplusplus
415} /* end extern "C" */
416#endif