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