NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
md5.c
Go to the documentation of this file.
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  */
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 
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 
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  ctx->hi += size >> 29;
219 
220  used = saved_lo & 0x3f;
221 
222  if (used) {
223  free = 64 - used;
224 
225  if (size < free) {
226  memcpy(&ctx->buffer[used], data, size);
227  return;
228  }
229 
230  memcpy(&ctx->buffer[used], data, free);
231  data = (unsigned char *)data + free;
232  size -= free;
233  body(ctx, ctx->buffer, 64);
234  }
235 
236  if (size >= 64) {
237  data = body(ctx, data, size & ~(unsigned long)0x3f);
238  size &= 0x3f;
239  }
240 
241  memcpy(ctx->buffer, data, size);
242 }
243 
244 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
245 {
246  unsigned long used, free;
247 
248  used = ctx->lo & 0x3f;
249 
250  ctx->buffer[used++] = 0x80;
251 
252  free = 64 - used;
253 
254  if (free < 8) {
255  memset(&ctx->buffer[used], 0, free);
256  body(ctx, ctx->buffer, 64);
257  used = 0;
258  free = 64;
259  }
260 
261  memset(&ctx->buffer[used], 0, free - 8);
262 
263  ctx->lo <<= 3;
264  ctx->buffer[56] = ctx->lo;
265  ctx->buffer[57] = ctx->lo >> 8;
266  ctx->buffer[58] = ctx->lo >> 16;
267  ctx->buffer[59] = ctx->lo >> 24;
268  ctx->buffer[60] = ctx->hi;
269  ctx->buffer[61] = ctx->hi >> 8;
270  ctx->buffer[62] = ctx->hi >> 16;
271  ctx->buffer[63] = ctx->hi >> 24;
272 
273  body(ctx, ctx->buffer, 64);
274 
275  result[0] = ctx->a;
276  result[1] = ctx->a >> 8;
277  result[2] = ctx->a >> 16;
278  result[3] = ctx->a >> 24;
279  result[4] = ctx->b;
280  result[5] = ctx->b >> 8;
281  result[6] = ctx->b >> 16;
282  result[7] = ctx->b >> 24;
283  result[8] = ctx->c;
284  result[9] = ctx->c >> 8;
285  result[10] = ctx->c >> 16;
286  result[11] = ctx->c >> 24;
287  result[12] = ctx->d;
288  result[13] = ctx->d >> 8;
289  result[14] = ctx->d >> 16;
290  result[15] = ctx->d >> 24;
291 
292  memset(ctx, 0, sizeof(*ctx));
293 }
294 
295 #endif