cf68e3ca6dd2298c595ac9920952c3acbfe42ed9
[awesomized/libmemcached] / libhashkit / md5.cc
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * HashKit library
4 *
5 * Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 */
37
38 /*
39 This Library has been modified from its original form by
40 Brian Aker (brian@tangent.org)
41
42 See below for original Copyright.
43 */
44 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
45 */
46
47 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
48 rights reserved.
49
50 License to copy and use this software is granted provided that it
51 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
52 Algorithm" in all material mentioning or referencing this software
53 or this function.
54
55 License is also granted to make and use derivative works provided
56 that such works are identified as "derived from the RSA Data
57 Security, Inc. MD5 Message-Digest Algorithm" in all material
58 mentioning or referencing the derived work.
59
60 RSA Data Security, Inc. makes no representations concerning either
61 the merchantability of this software or the suitability of this
62 software for any particular purpose. It is provided "as is"
63 without express or implied warranty of any kind.
64
65 These notices must be retained in any copies of any part of this
66 documentation and/or software.
67 */
68
69 #include <libhashkit/common.h>
70
71 #include <string.h>
72 #include <sys/types.h>
73
74 #pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations"
75
76 /* POINTER defines a generic pointer type */
77 typedef unsigned char *POINTER;
78 typedef const unsigned char *CONST_POINTER;
79
80
81 /* UINT4 defines a four byte word */
82 typedef unsigned int UINT4;
83
84
85 /* MD5 context. */
86 typedef struct {
87 UINT4 state[4]; /* state (ABCD) */
88 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
89 unsigned char buffer[64]; /* input buffer */
90 } MD5_CTX;
91
92 static void MD5Init (MD5_CTX *context); /* context */
93 static void MD5Update ( MD5_CTX *context, /* context */
94 const unsigned char *input, /* input block */
95 unsigned int inputLen); /* length of input block */
96 static void MD5Final ( unsigned char digest[16], /* message digest */
97 MD5_CTX *context); /* context */
98
99 /* Constants for MD5Transform routine. */
100
101 #define S11 7
102 #define S12 12
103 #define S13 17
104 #define S14 22
105 #define S21 5
106 #define S22 9
107 #define S23 14
108 #define S24 20
109 #define S31 4
110 #define S32 11
111 #define S33 16
112 #define S34 23
113 #define S41 6
114 #define S42 10
115 #define S43 15
116 #define S44 21
117
118
119 static void MD5Transform (UINT4 state[4],
120 const unsigned char block[64]);
121 static void Encode (unsigned char *output,
122 UINT4 *input,
123 unsigned int len);
124 static void Decode(UINT4 *output, const unsigned char *input, unsigned int len);
125
126 static unsigned char PADDING[64] = {
127 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
130 };
131
132 /* F, G, H and I are basic MD5 functions.
133 */
134 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
135 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
136 #define H(x, y, z) ((x) ^ (y) ^ (z))
137 #define I(x, y, z) ((y) ^ ((x) | (~z)))
138
139 /* ROTATE_LEFT rotates x left n bits.
140 */
141 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
142
143 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
144 Rotation is separate from addition to prevent recomputation.
145 */
146 #define FF(a, b, c, d, x, s, ac) { \
147 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
148 (a) = ROTATE_LEFT ((a), (s)); \
149 (a) += (b); \
150 }
151 #define GG(a, b, c, d, x, s, ac) { \
152 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
153 (a) = ROTATE_LEFT ((a), (s)); \
154 (a) += (b); \
155 }
156 #define HH(a, b, c, d, x, s, ac) { \
157 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
158 (a) = ROTATE_LEFT ((a), (s)); \
159 (a) += (b); \
160 }
161 #define II(a, b, c, d, x, s, ac) { \
162 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
163 (a) = ROTATE_LEFT ((a), (s)); \
164 (a) += (b); \
165 }
166
167
168 /*
169 Just a simple method for getting the signature
170 result must be == 16
171 */
172 void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result)
173 {
174 MD5_CTX my_md5;
175
176 MD5Init(&my_md5);
177 (void)MD5Update(&my_md5, key, length);
178 MD5Final(result, &my_md5);
179 }
180
181 /* MD5 initialization. Begins an MD5 operation, writing a new context.
182 */
183 static void MD5Init (MD5_CTX *context) /* context */
184 {
185 context->count[0] = context->count[1] = 0;
186 /* Load magic initialization constants.
187 */
188 context->state[0] = 0x67452301;
189 context->state[1] = 0xefcdab89;
190 context->state[2] = 0x98badcfe;
191 context->state[3] = 0x10325476;
192 }
193
194 /* MD5 block update operation. Continues an MD5 message-digest
195 operation, processing another message block, and updating the
196 context.
197 */
198
199 static void MD5Update (
200 MD5_CTX *context, /* context */
201 const unsigned char *input, /* input block */
202 unsigned int inputLen) /* length of input block */
203 {
204 unsigned int i, idx, partLen;
205
206 /* Compute number of bytes mod 64 */
207 idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
208
209
210 /* Update number of bits */
211 if ((context->count[0] += ((UINT4)inputLen << 3))
212 < ((UINT4)inputLen << 3))
213 context->count[1]++;
214 context->count[1] += ((UINT4)inputLen >> 29);
215
216 partLen = 64 - idx;
217
218 /* Transform as many times as possible.
219 */
220 if (inputLen >= partLen) {
221 memcpy((POINTER)&context->buffer[idx], (CONST_POINTER)input, partLen);
222 MD5Transform(context->state, context->buffer);
223
224 for (i = partLen; i + 63 < inputLen; i += 64)
225 MD5Transform (context->state, (CONST_POINTER)&input[i]);
226
227 idx = 0;
228 }
229 else
230 i = 0;
231
232 /* Buffer remaining input */
233 memcpy((POINTER)&context->buffer[idx], (CONST_POINTER)&input[i],
234 inputLen-i);
235 }
236
237 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
238 the message digest and zeroizing the context.
239 */
240
241 static void MD5Final (
242 unsigned char digest[16], /* message digest */
243 MD5_CTX *context) /* context */
244 {
245 unsigned char bits[8];
246 unsigned int idx, padLen;
247
248 /* Save number of bits */
249 Encode (bits, context->count, 8);
250
251 /* Pad out to 56 mod 64.
252 */
253 idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
254 padLen = (idx < 56) ? (56 - idx) : (120 - idx);
255 MD5Update (context, PADDING, padLen);
256
257 /* Append length (before padding) */
258 MD5Update (context, bits, 8);
259
260 /* Store state in digest */
261 Encode (digest, context->state, 16);
262
263 /* Zeroize sensitive information.
264 */
265 memset((POINTER)context, 0, sizeof (*context));
266 }
267
268 /* MD5 basic transformation. Transforms state based on block.
269 */
270 static void MD5Transform (
271 UINT4 state[4],
272 const unsigned char block[64])
273 {
274 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
275
276 Decode (x, block, 64);
277
278 /* Round 1 */
279 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
280 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
281 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
282 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
283 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
284 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
285 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
286 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
287 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
288 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
289 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
290 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
291 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
292 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
293 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
294 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
295
296 /* Round 2 */
297 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
298 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
299 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
300 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
301 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
302 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
303 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
304 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
305 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
306 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
307 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
308 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
309 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
310 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
311 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
312 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
313
314 /* Round 3 */
315 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
316 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
317 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
318 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
319 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
320 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
321 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
322 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
323 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
324 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
325 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
326 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
327 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
328 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
329 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
330 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
331
332 /* Round 4 */
333 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
334 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
335 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
336 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
337 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
338 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
339 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
340 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
341 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
342 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
343 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
344 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
345 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
346 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
347 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
348 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
349
350
351 state[0] += a;
352 state[1] += b;
353 state[2] += c;
354 state[3] += d;
355
356 /* Zeroize sensitive information.
357 */
358 memset((POINTER)x, 0, sizeof (x));
359 }
360
361 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
362 a multiple of 4.
363 */
364 static void Encode (
365 unsigned char *output,
366 UINT4 *input,
367 unsigned int len)
368 {
369 unsigned int i, j;
370
371 for (i = 0, j = 0; j < len; i++, j += 4) {
372 output[j] = (unsigned char)(input[i] & 0xff);
373 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
374 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
375 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
376 }
377 }
378
379
380 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
381 a multiple of 4.
382 */
383 static void Decode (
384 UINT4 *output,
385 const unsigned char *input,
386 unsigned int len)
387 {
388 unsigned int i, j;
389
390 for (i = 0, j = 0; j < len; i++, j += 4)
391 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
392 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
393 }
394
395 uint32_t hashkit_md5(const char *key, size_t key_length, void *context)
396 {
397 unsigned char results[16];
398 (void)context;
399
400 md5_signature((unsigned char*)key, (unsigned int)key_length, results);
401
402 return ((uint32_t) (results[3] & 0xFF) << 24)
403 | ((uint32_t) (results[2] & 0xFF) << 16)
404 | ((uint32_t) (results[1] & 0xFF) << 8)
405 | (results[0] & 0xFF);
406 }