1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at http://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
25 #ifndef CURL_DISABLE_CRYPTO_AUTH
30 #include "curl_hmac.h"
36 typedef gcry_md_hd_t MD5_CTX;
38 static void MD5_Init(MD5_CTX * ctx)
40 gcry_md_open(ctx, GCRY_MD_MD5, 0);
43 static void MD5_Update(MD5_CTX * ctx,
44 const unsigned char * input,
45 unsigned int inputLen)
47 gcry_md_write(*ctx, input, inputLen);
50 static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
52 memcpy(digest, gcry_md_read(*ctx, 0), 16);
59 /* When OpenSSL is available we use the MD5-function from OpenSSL */
62 # include <openssl/md5.h>
67 #else /* USE_SSLEAY */
68 /* When OpenSSL is not available we use this code segment */
70 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
73 License to copy and use this software is granted provided that it
74 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
75 Algorithm" in all material mentioning or referencing this software
78 License is also granted to make and use derivative works provided
79 that such works are identified as "derived from the RSA Data
80 Security, Inc. MD5 Message-Digest Algorithm" in all material
81 mentioning or referencing the derived work.
83 RSA Data Security, Inc. makes no representations concerning either
84 the merchantability of this software or the suitability of this
85 software for any particular purpose. It is provided "as is"
86 without express or implied warranty of any kind.
88 These notices must be retained in any copies of any part of this
89 documentation and/or software.
92 /* UINT4 defines a four byte word */
93 typedef unsigned int UINT4;
97 UINT4 state[4]; /* state (ABCD) */
98 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
99 unsigned char buffer[64]; /* input buffer */
102 typedef struct md5_ctx MD5_CTX;
104 static void MD5_Init(struct md5_ctx *);
105 static void MD5_Update(struct md5_ctx *, const unsigned char *, unsigned int);
106 static void MD5_Final(unsigned char [16], struct md5_ctx *);
108 /* Constants for MD5Transform routine.
128 static void MD5Transform(UINT4 [4], const unsigned char [64]);
129 static void Encode(unsigned char *, UINT4 *, unsigned int);
130 static void Decode(UINT4 *, const unsigned char *, unsigned int);
132 static const 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
138 /* F, G, H and I are basic MD5 functions.
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)))
145 /* ROTATE_LEFT rotates x left n bits.
147 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
149 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
150 Rotation is separate from addition to prevent recomputation.
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)); \
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)); \
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)); \
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)); \
173 /* MD5 initialization. Begins an MD5 operation, writing a new context.
175 static void MD5_Init(struct md5_ctx *context)
177 context->count[0] = context->count[1] = 0;
178 /* Load magic initialization constants. */
179 context->state[0] = 0x67452301;
180 context->state[1] = 0xefcdab89;
181 context->state[2] = 0x98badcfe;
182 context->state[3] = 0x10325476;
185 /* MD5 block update operation. Continues an MD5 message-digest
186 operation, processing another message block, and updating the
189 static void MD5_Update (struct md5_ctx *context, /* context */
190 const unsigned char *input, /* input block */
191 unsigned int inputLen) /* length of input block */
193 unsigned int i, bufindex, partLen;
195 /* Compute number of bytes mod 64 */
196 bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
198 /* Update number of bits */
199 if((context->count[0] += ((UINT4)inputLen << 3))
200 < ((UINT4)inputLen << 3))
202 context->count[1] += ((UINT4)inputLen >> 29);
204 partLen = 64 - bufindex;
206 /* Transform as many times as possible. */
207 if(inputLen >= partLen) {
208 memcpy(&context->buffer[bufindex], input, partLen);
209 MD5Transform(context->state, context->buffer);
211 for (i = partLen; i + 63 < inputLen; i += 64)
212 MD5Transform(context->state, &input[i]);
219 /* Buffer remaining input */
220 memcpy(&context->buffer[bufindex], &input[i], inputLen-i);
223 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
224 the message digest and zeroizing the context.
226 static void MD5_Final(unsigned char digest[16], /* message digest */
227 struct md5_ctx *context) /* context */
229 unsigned char bits[8];
230 unsigned int count, padLen;
232 /* Save number of bits */
233 Encode (bits, context->count, 8);
235 /* Pad out to 56 mod 64. */
236 count = (unsigned int)((context->count[0] >> 3) & 0x3f);
237 padLen = (count < 56) ? (56 - count) : (120 - count);
238 MD5_Update (context, PADDING, padLen);
240 /* Append length (before padding) */
241 MD5_Update (context, bits, 8);
243 /* Store state in digest */
244 Encode (digest, context->state, 16);
246 /* Zeroize sensitive information. */
247 memset ((void *)context, 0, sizeof (*context));
250 /* MD5 basic transformation. Transforms state based on block. */
251 static void MD5Transform(UINT4 state[4],
252 const unsigned char block[64])
254 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
256 Decode (x, block, 64);
259 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
260 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
261 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
262 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
263 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
264 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
265 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
266 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
267 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
268 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
269 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
270 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
271 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
272 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
273 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
274 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
277 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
278 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
279 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
280 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
281 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
282 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
283 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
284 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
285 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
286 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
287 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
288 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
289 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
290 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
291 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
292 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
295 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
296 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
297 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
298 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
299 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
300 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
301 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
302 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
303 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
304 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
305 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
306 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
307 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
308 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
309 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
310 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
313 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
314 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
315 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
316 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
317 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
318 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
319 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
320 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
321 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
322 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
323 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
324 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
325 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
326 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
327 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
328 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
335 /* Zeroize sensitive information. */
336 memset((void *)x, 0, sizeof (x));
339 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
342 static void Encode (unsigned char *output,
348 for (i = 0, j = 0; j < len; i++, j += 4) {
349 output[j] = (unsigned char)(input[i] & 0xff);
350 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
351 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
352 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
356 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
359 static void Decode (UINT4 *output,
360 const unsigned char *input,
365 for (i = 0, j = 0; j < len; i++, j += 4)
366 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
367 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
370 #endif /* USE_SSLEAY */
372 #endif /* USE_GNUTLS */
374 const HMAC_params Curl_HMAC_MD5[] = {
376 (HMAC_hinit_func) MD5_Init, /* Hash initialization function. */
377 (HMAC_hupdate_func) MD5_Update, /* Hash update function. */
378 (HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */
379 sizeof(MD5_CTX), /* Size of hash context structure. */
380 64, /* Maximum key length. */
381 16 /* Result size. */
386 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
387 const unsigned char *input)
391 MD5_Update(&ctx, input, (unsigned int)strlen((char *)input));
392 MD5_Final(outbuffer, &ctx);
395 #endif /* CURL_DISABLE_CRYPTO_AUTH */