~brianaker/libmemcached/1164440

1072.1.21 by Brian Aker
Fix copyright headers in libhashkit.
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
644 by Brian Aker
Adding back libhashkit.
38
/*
908.1.1 by Trond Norbye
Don't use __attribute__((unused))
39
  This Library has been modified from its original form by
644 by Brian Aker
Adding back libhashkit.
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
929.1.21 by Brian Aker
Fixes all current issues with hashkit tests.
69
#include <libhashkit/common.h>
644 by Brian Aker
Adding back libhashkit.
70
71
#include <string.h>
72
#include <sys/types.h>
73
1150.1.1 by Brian Aker
Fix OSX/clang compiler warning.
74
#define GCC_VERSION (__GNUC__ * 10000 \
75
                     + __GNUC_MINOR__ * 100 \
76
                     + __GNUC_PATCHLEVEL__)
77
78
#if GCC_VERSION > 40600
79
# pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations"
80
#endif
1148.1.5 by Brian Aker
Update for new warnings.
81
644 by Brian Aker
Adding back libhashkit.
82
/* POINTER defines a generic pointer type */
83
typedef unsigned char *POINTER;
929.1.88 by Brian Aker
Merge in conversion to C++.
84
typedef const unsigned char *CONST_POINTER;
644 by Brian Aker
Adding back libhashkit.
85
86
87
/* UINT4 defines a four byte word */
88
typedef unsigned int UINT4;
89
90
91
/* MD5 context. */
92
typedef struct {
93
  UINT4 state[4];                                   /* state (ABCD) */
94
  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
95
  unsigned char buffer[64];                         /* input buffer */
96
} MD5_CTX;
97
98
static void MD5Init (MD5_CTX *context);      /* context */
99
static void MD5Update ( MD5_CTX *context,                                        /* context */
100
                        const unsigned char *input,                              /* input block */
101
                        unsigned int inputLen);                     /* length of input block */
102
static void MD5Final ( unsigned char digest[16],                         /* message digest */
103
                       MD5_CTX *context);                              /* context */
104
105
/* Constants for MD5Transform routine. */
106
107
#define S11 7
108
#define S12 12
109
#define S13 17
110
#define S14 22
111
#define S21 5
112
#define S22 9
113
#define S23 14
114
#define S24 20
115
#define S31 4
116
#define S32 11
117
#define S33 16
118
#define S34 23
119
#define S41 6
120
#define S42 10
121
#define S43 15
122
#define S44 21
123
124
125
static void MD5Transform (UINT4 state[4],
929.1.88 by Brian Aker
Merge in conversion to C++.
126
                          const unsigned char block[64]);
644 by Brian Aker
Adding back libhashkit.
127
static void Encode (unsigned char *output,
128
                    UINT4 *input,
129
                    unsigned int len);
929.1.88 by Brian Aker
Merge in conversion to C++.
130
static void Decode(UINT4 *output, const unsigned char *input, unsigned int len);
644 by Brian Aker
Adding back libhashkit.
131
132
static unsigned char PADDING[64] = {
133
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
136
};
137
138
/* F, G, H and I are basic MD5 functions.
139
 */
140
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
141
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
142
#define H(x, y, z) ((x) ^ (y) ^ (z))
143
#define I(x, y, z) ((y) ^ ((x) | (~z)))
144
145
/* ROTATE_LEFT rotates x left n bits.
146
 */
147
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
148
149
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
150
Rotation is separate from addition to prevent recomputation.
151
 */
152
#define FF(a, b, c, d, x, s, ac) { \
153
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
154
 (a) = ROTATE_LEFT ((a), (s)); \
155
 (a) += (b); \
156
  }
157
#define GG(a, b, c, d, x, s, ac) { \
158
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
159
 (a) = ROTATE_LEFT ((a), (s)); \
160
 (a) += (b); \
161
  }
162
#define HH(a, b, c, d, x, s, ac) { \
163
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
164
 (a) = ROTATE_LEFT ((a), (s)); \
165
 (a) += (b); \
166
  }
167
#define II(a, b, c, d, x, s, ac) { \
168
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
169
 (a) = ROTATE_LEFT ((a), (s)); \
170
 (a) += (b); \
171
  }
172
173
908.1.1 by Trond Norbye
Don't use __attribute__((unused))
174
/*
644 by Brian Aker
Adding back libhashkit.
175
  Just a simple method for getting the signature
176
  result must be == 16
177
*/
178
void md5_signature(const unsigned char *key, unsigned int length, unsigned char *result)
179
{
180
    MD5_CTX my_md5;
181
182
    MD5Init(&my_md5);
183
    (void)MD5Update(&my_md5, key, length);
184
    MD5Final(result, &my_md5);
185
}
186
187
/* MD5 initialization. Begins an MD5 operation, writing a new context.
188
 */
189
static void MD5Init (MD5_CTX *context)      /* context */
190
{
191
  context->count[0] = context->count[1] = 0;
192
  /* Load magic initialization constants.
193
*/
194
  context->state[0] = 0x67452301;
195
  context->state[1] = 0xefcdab89;
196
  context->state[2] = 0x98badcfe;
197
  context->state[3] = 0x10325476;
198
}
199
200
/* MD5 block update operation. Continues an MD5 message-digest
201
  operation, processing another message block, and updating the
202
  context.
203
 */
204
205
static void MD5Update (
206
                       MD5_CTX *context,                                        /* context */
207
                       const unsigned char *input,                              /* input block */
208
                       unsigned int inputLen)                     /* length of input block */
209
{
210
  unsigned int i, idx, partLen;
211
212
  /* Compute number of bytes mod 64 */
213
  idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
214
215
216
  /* Update number of bits */
217
  if ((context->count[0] += ((UINT4)inputLen << 3))
774 by Brian Aker
More Cleanup
218
      < ((UINT4)inputLen << 3))
219
    context->count[1]++;
644 by Brian Aker
Adding back libhashkit.
220
  context->count[1] += ((UINT4)inputLen >> 29);
221
222
  partLen = 64 - idx;
223
224
  /* Transform as many times as possible.
225
*/
226
  if (inputLen >= partLen) {
929.1.88 by Brian Aker
Merge in conversion to C++.
227
    memcpy((POINTER)&context->buffer[idx], (CONST_POINTER)input, partLen);
228
    MD5Transform(context->state, context->buffer);
229
230
    for (i = partLen; i + 63 < inputLen; i += 64)
231
      MD5Transform (context->state, (CONST_POINTER)&input[i]);
232
233
    idx = 0;
644 by Brian Aker
Adding back libhashkit.
234
  }
235
  else
929.1.88 by Brian Aker
Merge in conversion to C++.
236
    i = 0;
644 by Brian Aker
Adding back libhashkit.
237
238
  /* Buffer remaining input */
929.1.88 by Brian Aker
Merge in conversion to C++.
239
  memcpy((POINTER)&context->buffer[idx], (CONST_POINTER)&input[i],
240
         inputLen-i);
644 by Brian Aker
Adding back libhashkit.
241
}
242
243
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
244
  the message digest and zeroizing the context.
245
 */
246
247
static void MD5Final (
248
                      unsigned char digest[16],                         /* message digest */
249
                      MD5_CTX *context)                              /* context */
250
{
251
  unsigned char bits[8];
252
  unsigned int idx, padLen;
253
254
  /* Save number of bits */
255
  Encode (bits, context->count, 8);
256
257
  /* Pad out to 56 mod 64.
258
*/
259
  idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
260
  padLen = (idx < 56) ? (56 - idx) : (120 - idx);
261
  MD5Update (context, PADDING, padLen);
262
263
  /* Append length (before padding) */
264
  MD5Update (context, bits, 8);
265
266
  /* Store state in digest */
267
  Encode (digest, context->state, 16);
268
269
  /* Zeroize sensitive information.
270
*/
271
  memset((POINTER)context, 0, sizeof (*context));
272
}
273
274
/* MD5 basic transformation. Transforms state based on block.
275
 */
276
static void MD5Transform (
277
                          UINT4 state[4],
929.1.88 by Brian Aker
Merge in conversion to C++.
278
                          const unsigned char block[64])
644 by Brian Aker
Adding back libhashkit.
279
{
280
  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
281
282
  Decode (x, block, 64);
283
284
  /* Round 1 */
285
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
286
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
287
  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
288
  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
289
  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
290
  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
291
  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
292
  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
293
  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
294
  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
295
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
296
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
297
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
298
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
299
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
300
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
301
302
 /* Round 2 */
303
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
304
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
305
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
306
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
307
  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
308
  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
309
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
310
  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
311
  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
312
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
313
  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
314
  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
315
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
316
  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
317
  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
318
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
319
320
  /* Round 3 */
321
  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
322
  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
323
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
324
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
325
  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
326
  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
327
  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
328
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
329
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
330
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
331
  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
332
  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
333
  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
334
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
335
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
336
  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
337
338
  /* Round 4 */
339
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
340
  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
341
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
342
  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
343
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
344
  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
345
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
346
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
347
  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
348
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
349
  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
350
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
351
  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
352
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
353
  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
354
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
355
356
357
  state[0] += a;
358
  state[1] += b;
359
  state[2] += c;
360
  state[3] += d;
361
362
  /* Zeroize sensitive information.
363
*/
364
  memset((POINTER)x, 0, sizeof (x));
365
}
366
367
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
368
  a multiple of 4.
369
 */
370
static void Encode (
371
unsigned char *output,
372
UINT4 *input,
373
unsigned int len)
374
{
375
  unsigned int i, j;
376
377
  for (i = 0, j = 0; j < len; i++, j += 4) {
378
 output[j] = (unsigned char)(input[i] & 0xff);
379
 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
380
 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
381
 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
382
  }
383
}
384
385
386
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
387
  a multiple of 4.
388
 */
389
static void Decode (
929.1.88 by Brian Aker
Merge in conversion to C++.
390
                    UINT4 *output,
391
                    const unsigned char *input,
392
                    unsigned int len)
644 by Brian Aker
Adding back libhashkit.
393
{
394
  unsigned int i, j;
395
396
  for (i = 0, j = 0; j < len; i++, j += 4)
929.1.88 by Brian Aker
Merge in conversion to C++.
397
    output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
398
      (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
644 by Brian Aker
Adding back libhashkit.
399
}
400
908.1.1 by Trond Norbye
Don't use __attribute__((unused))
401
uint32_t hashkit_md5(const char *key, size_t key_length, void *context)
644 by Brian Aker
Adding back libhashkit.
402
{
403
  unsigned char results[16];
908.1.1 by Trond Norbye
Don't use __attribute__((unused))
404
  (void)context;
644 by Brian Aker
Adding back libhashkit.
405
406
  md5_signature((unsigned char*)key, (unsigned int)key_length, results);
407
408
  return ((uint32_t) (results[3] & 0xFF) << 24)
409
    | ((uint32_t) (results[2] & 0xFF) << 16)
410
    | ((uint32_t) (results[1] & 0xFF) << 8)
411
    | (results[0] & 0xFF);
412
}