1 /*
2  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
3  * MD5 Message-Digest Algorithm (RFC 1321).
4  *
5  * Homepage:
6  * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
7  *
8  * Author:
9  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
10  *
11  * This software was written by Alexander Peslyak in 2001.  No copyright is
12  * claimed, and the software is hereby placed in the public domain.
13  * In case this attempt to disclaim copyright and place the software in the
14  * public domain is deemed null and void, then the software is
15  * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
16  * general public under the following terms:
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted.
20  *
21  * There's ABSOLUTELY NO WARRANTY, express or implied.
22  *
23  * (This is a heavily cut-down "BSD license".)
24  *
25  * This differs from Colin Plumb's older public domain implementation in that
26  * no exactly 32-bit integer data type is required (any 32-bit or wider
27  * unsigned integer data type will do), there's no compile-time endianness
28  * configuration, and the function prototypes match OpenSSL's.  No code from
29  * Colin Plumb's implementation has been reused; this comment merely compares
30  * the properties of the two independent implementations.
31  *
32  * The primary goals of this implementation are portability and ease of use.
33  * It is meant to be fast, but not as fast as possible.  Some known
34  * optimizations are not included to reduce source code size and avoid
35  * compile-time configuration.
36  */
37 
38 #ifndef HAVE_OPENSSL
39 
40 #include <string.h>
41 
42 #include "md5.h"
43 
44 /*
45  * The basic MD5 functions.
46  *
47  * F and G are optimized compared to their RFC 1321 definitions for
48  * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
49  * implementation.
50  */
51 #define F(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
52 #define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
53 #define H(x, y, z)			((x) ^ (y) ^ (z))
54 #define I(x, y, z)			((y) ^ ((x) | ~(z)))
55 
56 /*
57  * The MD5 transformation for all four rounds.
58  */
59 #define STEP(f, a, b, c, d, x, t, s) \
60 	(a) += f((b), (c), (d)) + (x) + (t); \
61 	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
62 	(a) += (b);
63 
64 /*
65  * SET reads 4 input bytes in little-endian byte order and stores them
66  * in a properly aligned word in host byte order.
67  *
68  * The check for little-endian architectures that tolerate unaligned
69  * memory accesses is just an optimization.  Nothing will break if it
70  * doesn't work.
71  */
72 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
73 #define SET(n) \
74 	(*(MD5_u32plus *)&ptr[(n) * 4])
75 #define GET(n) \
76 	SET(n)
77 #else
78 #define SET(n) \
79 	(ctx->block[(n)] = \
80 	(MD5_u32plus)ptr[(n) * 4] | \
81 	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
82 	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
83 	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
84 #define GET(n) \
85 	(ctx->block[(n)])
86 #endif
87 
88 /*
89  * This processes one or more 64-byte data blocks, but does NOT update
90  * the bit counters.  There are no alignment requirements.
91  */
body(MD5_CTX *ctx, void *data, unsigned long size)92 static void *body(MD5_CTX *ctx, void *data, unsigned long size)
93 {
94     unsigned char *ptr;
95     MD5_u32plus a, b, c, d;
96     MD5_u32plus saved_a, saved_b, saved_c, saved_d;
97 
98     ptr = data;
99 
100     a = ctx->a;
101     b = ctx->b;
102     c = ctx->c;
103     d = ctx->d;
104 
105     do {
106         saved_a = a;
107         saved_b = b;
108         saved_c = c;
109         saved_d = d;
110 
111         /* Round 1 */
112         STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
113         STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
114         STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
115         STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
116         STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
117         STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
118         STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
119         STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
120         STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
121         STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
122         STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
123         STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
124         STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
125         STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
126         STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
127         STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
128 
129         /* Round 2 */
130         STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
131         STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
132         STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
133         STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
134         STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
135         STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
136         STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
137         STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
138         STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
139         STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
140         STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
141         STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
142         STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
143         STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
144         STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
145         STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
146 
147         /* Round 3 */
148         STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
149         STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
150         STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
151         STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
152         STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
153         STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
154         STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
155         STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
156         STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
157         STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
158         STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
159         STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
160         STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
161         STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
162         STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
163         STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
164 
165         /* Round 4 */
166         STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
167         STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
168         STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
169         STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
170         STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
171         STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
172         STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
173         STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
174         STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
175         STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
176         STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
177         STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
178         STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
179         STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
180         STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
181         STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
182 
183         a += saved_a;
184         b += saved_b;
185         c += saved_c;
186         d += saved_d;
187 
188         ptr += 64;
189     } while (size -= 64);
190 
191     ctx->a = a;
192     ctx->b = b;
193     ctx->c = c;
194     ctx->d = d;
195 
196     return ptr;
197 }
198 
MD5_Init(MD5_CTX *ctx)199 void MD5_Init(MD5_CTX *ctx)
200 {
201     ctx->a = 0x67452301;
202     ctx->b = 0xefcdab89;
203     ctx->c = 0x98badcfe;
204     ctx->d = 0x10325476;
205 
206     ctx->lo = 0;
207     ctx->hi = 0;
208 }
209 
MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)210 void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
211 {
212     MD5_u32plus saved_lo;
213     unsigned long used, free;
214 
215     saved_lo = ctx->lo;
216     if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) {
217         ctx->hi++;
218     }
219     ctx->hi += size >> 29;
220 
221     used = saved_lo & 0x3f;
222 
223     if (used) {
224         free = 64 - used;
225 
226         if (size < free) {
227             memcpy(&ctx->buffer[used], data, size);
228             return;
229         }
230 
231         memcpy(&ctx->buffer[used], data, free);
232         data = (unsigned char *)data + free;
233         size -= free;
234         body(ctx, ctx->buffer, 64);
235     }
236 
237     if (size >= 64) {
238         data = body(ctx, data, size & ~(unsigned long)0x3f);
239         size &= 0x3f;
240     }
241 
242     memcpy(ctx->buffer, data, size);
243 }
244 
MD5_Final(unsigned char *result, MD5_CTX *ctx)245 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
246 {
247     unsigned long used, free;
248 
249     used = ctx->lo & 0x3f;
250 
251     ctx->buffer[used++] = 0x80;
252 
253     free = 64 - used;
254 
255     if (free < 8) {
256         memset(&ctx->buffer[used], 0, free);
257         body(ctx, ctx->buffer, 64);
258         used = 0;
259         free = 64;
260     }
261 
262     memset(&ctx->buffer[used], 0, free - 8);
263 
264     ctx->lo <<= 3;
265     ctx->buffer[56] = ctx->lo;
266     ctx->buffer[57] = ctx->lo >> 8;
267     ctx->buffer[58] = ctx->lo >> 16;
268     ctx->buffer[59] = ctx->lo >> 24;
269     ctx->buffer[60] = ctx->hi;
270     ctx->buffer[61] = ctx->hi >> 8;
271     ctx->buffer[62] = ctx->hi >> 16;
272     ctx->buffer[63] = ctx->hi >> 24;
273 
274     body(ctx, ctx->buffer, 64);
275 
276     result[0] = ctx->a;
277     result[1] = ctx->a >> 8;
278     result[2] = ctx->a >> 16;
279     result[3] = ctx->a >> 24;
280     result[4] = ctx->b;
281     result[5] = ctx->b >> 8;
282     result[6] = ctx->b >> 16;
283     result[7] = ctx->b >> 24;
284     result[8] = ctx->c;
285     result[9] = ctx->c >> 8;
286     result[10] = ctx->c >> 16;
287     result[11] = ctx->c >> 24;
288     result[12] = ctx->d;
289     result[13] = ctx->d >> 8;
290     result[14] = ctx->d >> 16;
291     result[15] = ctx->d >> 24;
292 
293     memset(ctx, 0, sizeof(*ctx));
294 }
295 
296 #endif
297