1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
5 * Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
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
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
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.
39 This Library has been modified from its original form by
40 Brian Aker (brian@tangent.org)
42 See below for original Copyright.
44 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
47 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
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
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.
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.
65 These notices must be retained in any copies of any part of this
66 documentation and/or software.
69 #include <libhashkit/common.h>
72 #include <sys/types.h>
74 #pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations"
76 /* POINTER defines a generic pointer type */
77 typedef unsigned char *POINTER
;
78 typedef const unsigned char *CONST_POINTER
;
81 /* UINT4 defines a four byte word */
82 typedef unsigned int UINT4
;
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 */
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 */
99 /* Constants for MD5Transform routine. */
119 static void MD5Transform (UINT4 state
[4],
120 const unsigned char block
[64]);
121 static void Encode (unsigned char *output
,
124 static void Decode(UINT4
*output
, const unsigned char *input
, unsigned int len
);
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
132 /* F, G, H and I are basic MD5 functions.
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)))
139 /* ROTATE_LEFT rotates x left n bits.
141 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
143 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
144 Rotation is separate from addition to prevent recomputation.
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)); \
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)); \
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)); \
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)); \
169 Just a simple method for getting the signature
172 void md5_signature(const unsigned char *key
, unsigned int length
, unsigned char *result
)
177 (void)MD5Update(&my_md5
, key
, length
);
178 MD5Final(result
, &my_md5
);
181 /* MD5 initialization. Begins an MD5 operation, writing a new context.
183 static void MD5Init (MD5_CTX
*context
) /* context */
185 context
->count
[0] = context
->count
[1] = 0;
186 /* Load magic initialization constants.
188 context
->state
[0] = 0x67452301;
189 context
->state
[1] = 0xefcdab89;
190 context
->state
[2] = 0x98badcfe;
191 context
->state
[3] = 0x10325476;
194 /* MD5 block update operation. Continues an MD5 message-digest
195 operation, processing another message block, and updating the
199 static void MD5Update (
200 MD5_CTX
*context
, /* context */
201 const unsigned char *input
, /* input block */
202 unsigned int inputLen
) /* length of input block */
204 unsigned int i
, idx
, partLen
;
206 /* Compute number of bytes mod 64 */
207 idx
= (unsigned int)((context
->count
[0] >> 3) & 0x3F);
210 /* Update number of bits */
211 if ((context
->count
[0] += ((UINT4
)inputLen
<< 3))
212 < ((UINT4
)inputLen
<< 3))
214 context
->count
[1] += ((UINT4
)inputLen
>> 29);
218 /* Transform as many times as possible.
220 if (inputLen
>= partLen
) {
221 memcpy((POINTER
)&context
->buffer
[idx
], (CONST_POINTER
)input
, partLen
);
222 MD5Transform(context
->state
, context
->buffer
);
224 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64)
225 MD5Transform (context
->state
, (CONST_POINTER
)&input
[i
]);
232 /* Buffer remaining input */
233 memcpy((POINTER
)&context
->buffer
[idx
], (CONST_POINTER
)&input
[i
],
237 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
238 the message digest and zeroizing the context.
241 static void MD5Final (
242 unsigned char digest
[16], /* message digest */
243 MD5_CTX
*context
) /* context */
245 unsigned char bits
[8];
246 unsigned int idx
, padLen
;
248 /* Save number of bits */
249 Encode (bits
, context
->count
, 8);
251 /* Pad out to 56 mod 64.
253 idx
= (unsigned int)((context
->count
[0] >> 3) & 0x3f);
254 padLen
= (idx
< 56) ? (56 - idx
) : (120 - idx
);
255 MD5Update (context
, PADDING
, padLen
);
257 /* Append length (before padding) */
258 MD5Update (context
, bits
, 8);
260 /* Store state in digest */
261 Encode (digest
, context
->state
, 16);
263 /* Zeroize sensitive information.
265 memset((POINTER
)context
, 0, sizeof (*context
));
268 /* MD5 basic transformation. Transforms state based on block.
270 static void MD5Transform (
272 const unsigned char block
[64])
274 UINT4 a
= state
[0], b
= state
[1], c
= state
[2], d
= state
[3], x
[16];
276 Decode (x
, block
, 64);
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 */
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 */
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 */
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 */
356 /* Zeroize sensitive information.
358 memset((POINTER
)x
, 0, sizeof (x
));
361 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
365 unsigned char *output
,
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);
380 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
385 const unsigned char *input
,
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);
395 uint32_t hashkit_md5(const char *key
, size_t key_length
, void *context
)
397 unsigned char results
[16];
400 md5_signature((unsigned char*)key
, (unsigned int)key_length
, results
);
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);