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 H2(x, y, z)			((x) ^ ((y) ^ (z)))
55 #define I(x, y, z)			((y) ^ ((x) | ~(z)))
56 
57 /*
58  * The MD5 transformation for all four rounds.
59  */
60 #define STEP(f, a, b, c, d, x, t, s) \
61 	(a) += f((b), (c), (d)) + (x) + (t); \
62 	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
63 	(a) += (b);
64 
65 /*
66  * SET reads 4 input bytes in little-endian byte order and stores them in a
67  * properly aligned word in host byte order.
68  *
69  * The check for little-endian architectures that tolerate unaligned memory
70  * accesses is just an optimization.  Nothing will break if it fails to detect
71  * a suitable architecture.
72  *
73  * Unfortunately, this optimization may be a C strict aliasing rules violation
74  * if the caller's data buffer has effective type that cannot be aliased by
75  * MD5_u32plus.  In practice, this problem may occur if these MD5 routines are
76  * inlined into a calling function, or with future and dangerously advanced
77  * link-time optimizations.  For the time being, keeping these MD5 routines in
78  * their own translation unit avoids the problem.
79  */
80 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
81 #define SET(n) \
82 	(*(MD5_u32plus *)&ptr[(n) * 4])
83 #define GET(n) \
84 	SET(n)
85 #else
86 #define SET(n) \
87 	(ctx->block[(n)] = \
88 	(MD5_u32plus)ptr[(n) * 4] | \
89 	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
90 	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
91 	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
92 #define GET(n) \
93 	(ctx->block[(n)])
94 #endif
95 
96 /*
97  * This processes one or more 64-byte data blocks, but does NOT update the bit
98  * counters.  There are no alignment requirements.
99  */
body(MD5_CTX * ctx,const void * data,unsigned long size)100 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
101 {
102 	const unsigned char *ptr;
103 	MD5_u32plus a, b, c, d;
104 	MD5_u32plus saved_a, saved_b, saved_c, saved_d;
105 
106 	ptr = (const unsigned char *)data;
107 
108 	a = ctx->a;
109 	b = ctx->b;
110 	c = ctx->c;
111 	d = ctx->d;
112 
113 	do {
114 		saved_a = a;
115 		saved_b = b;
116 		saved_c = c;
117 		saved_d = d;
118 
119 /* Round 1 */
120 		STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
121 		STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
122 		STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
123 		STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
124 		STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
125 		STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
126 		STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
127 		STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
128 		STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
129 		STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
130 		STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
131 		STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
132 		STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
133 		STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
134 		STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
135 		STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
136 
137 /* Round 2 */
138 		STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
139 		STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
140 		STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
141 		STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
142 		STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
143 		STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
144 		STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
145 		STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
146 		STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
147 		STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
148 		STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
149 		STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
150 		STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
151 		STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
152 		STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
153 		STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
154 
155 /* Round 3 */
156 		STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
157 		STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
158 		STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
159 		STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
160 		STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
161 		STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
162 		STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
163 		STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
164 		STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
165 		STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
166 		STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
167 		STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
168 		STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
169 		STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
170 		STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
171 		STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
172 
173 /* Round 4 */
174 		STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
175 		STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
176 		STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
177 		STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
178 		STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
179 		STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
180 		STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
181 		STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
182 		STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
183 		STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
184 		STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
185 		STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
186 		STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
187 		STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
188 		STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
189 		STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
190 
191 		a += saved_a;
192 		b += saved_b;
193 		c += saved_c;
194 		d += saved_d;
195 
196 		ptr += 64;
197 	} while (size -= 64);
198 
199 	ctx->a = a;
200 	ctx->b = b;
201 	ctx->c = c;
202 	ctx->d = d;
203 
204 	return ptr;
205 }
206 
MD5_Init(MD5_CTX * ctx)207 void MD5_Init(MD5_CTX *ctx)
208 {
209 	ctx->a = 0x67452301;
210 	ctx->b = 0xefcdab89;
211 	ctx->c = 0x98badcfe;
212 	ctx->d = 0x10325476;
213 
214 	ctx->lo = 0;
215 	ctx->hi = 0;
216 }
217 
MD5_Update(MD5_CTX * ctx,const void * data,unsigned long size)218 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
219 {
220 	MD5_u32plus saved_lo;
221 	unsigned long used, available;
222 
223 	saved_lo = ctx->lo;
224 	if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
225 		ctx->hi++;
226 	ctx->hi += size >> 29;
227 
228 	used = saved_lo & 0x3f;
229 
230 	if (used) {
231 		available = 64 - used;
232 
233 		if (size < available) {
234 			memcpy(&ctx->buffer[used], data, size);
235 			return;
236 		}
237 
238 		memcpy(&ctx->buffer[used], data, available);
239 		data = (const unsigned char *)data + available;
240 		size -= available;
241 		body(ctx, ctx->buffer, 64);
242 	}
243 
244 	if (size >= 64) {
245 		data = body(ctx, data, size & ~(unsigned long)0x3f);
246 		size &= 0x3f;
247 	}
248 
249 	memcpy(ctx->buffer, data, size);
250 }
251 
252 #define OUT(dst, src) \
253 	(dst)[0] = (unsigned char)(src); \
254 	(dst)[1] = (unsigned char)((src) >> 8); \
255 	(dst)[2] = (unsigned char)((src) >> 16); \
256 	(dst)[3] = (unsigned char)((src) >> 24);
257 
MD5_Final(unsigned char * result,MD5_CTX * ctx)258 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
259 {
260 	unsigned long used, available;
261 
262 	used = ctx->lo & 0x3f;
263 
264 	ctx->buffer[used++] = 0x80;
265 
266 	available = 64 - used;
267 
268 	if (available < 8) {
269 		memset(&ctx->buffer[used], 0, available);
270 		body(ctx, ctx->buffer, 64);
271 		used = 0;
272 		available = 64;
273 	}
274 
275 	memset(&ctx->buffer[used], 0, available - 8);
276 
277 	ctx->lo <<= 3;
278 	OUT(&ctx->buffer[56], ctx->lo)
279 	OUT(&ctx->buffer[60], ctx->hi)
280 
281 	body(ctx, ctx->buffer, 64);
282 
283 	OUT(&result[0], ctx->a)
284 	OUT(&result[4], ctx->b)
285 	OUT(&result[8], ctx->c)
286 	OUT(&result[12], ctx->d)
287 
288 	memset(ctx, 0, sizeof(*ctx));
289 }
290 
291 #endif
292