1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, 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 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifndef CURL_DISABLE_CRYPTO_AUTH
28 #include "curl_hmac.h"
29 #include "curl_warnless.h"
31 #include "curl_memory.h"
33 #if defined(USE_GNUTLS_NETTLE)
35 #include <nettle/md5.h>
36 /* The last #include file should be: */
37 #include "curl_memdebug.h"
39 typedef struct md5_ctx MD5_CTX;
41 static void MD5_Init(MD5_CTX * ctx)
46 static void MD5_Update(MD5_CTX * ctx,
47 const unsigned char * input,
48 unsigned int inputLen)
50 md5_update(ctx, inputLen, input);
53 static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
55 md5_digest(ctx, 16, digest);
58 #elif defined(USE_GNUTLS)
61 /* The last #include file should be: */
62 #include "curl_memdebug.h"
64 typedef gcry_md_hd_t MD5_CTX;
66 static void MD5_Init(MD5_CTX * ctx)
68 gcry_md_open(ctx, GCRY_MD_MD5, 0);
71 static void MD5_Update(MD5_CTX * ctx,
72 const unsigned char * input,
73 unsigned int inputLen)
75 gcry_md_write(*ctx, input, inputLen);
78 static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
80 memcpy(digest, gcry_md_read(*ctx, 0), 16);
84 #elif defined(USE_SSLEAY)
85 /* When OpenSSL is available we use the MD5-function from OpenSSL */
88 # include <openssl/md5.h>
93 #elif defined(__MAC_10_4) || defined(__IPHONE_5_0)
95 /* For Apple operating systems: CommonCrypto has the functions we need.
96 The library's headers are even backward-compatible with OpenSSL's
97 headers as long as we define COMMON_DIGEST_FOR_OPENSSL first.
99 These functions are available on Tiger and later, as well as iOS 5.0
100 and later. If you're building for an older cat, well, sorry. */
101 # define COMMON_DIGEST_FOR_OPENSSL
102 # include <CommonCrypto/CommonDigest.h>
104 #elif defined(_WIN32)
106 #include <wincrypt.h>
109 HCRYPTPROV hCryptProv;
113 static void MD5_Init(MD5_CTX *ctx)
115 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
116 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
117 CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
121 static void MD5_Update(MD5_CTX *ctx,
122 const unsigned char *input,
123 unsigned int inputLen)
125 CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
128 static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
130 unsigned long length;
131 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
133 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
135 CryptDestroyHash(ctx->hHash);
137 CryptReleaseContext(ctx->hCryptProv, 0);
141 /* When no other crypto library is available we use this code segment */
143 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
146 License to copy and use this software is granted provided that it
147 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
148 Algorithm" in all material mentioning or referencing this software
151 License is also granted to make and use derivative works provided
152 that such works are identified as "derived from the RSA Data
153 Security, Inc. MD5 Message-Digest Algorithm" in all material
154 mentioning or referencing the derived work.
156 RSA Data Security, Inc. makes no representations concerning either
157 the merchantability of this software or the suitability of this
158 software for any particular purpose. It is provided "as is"
159 without express or implied warranty of any kind.
161 These notices must be retained in any copies of any part of this
162 documentation and/or software.
165 /* UINT4 defines a four byte word */
166 typedef unsigned int UINT4;
170 UINT4 state[4]; /* state (ABCD) */
171 UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
172 unsigned char buffer[64]; /* input buffer */
175 typedef struct md5_ctx MD5_CTX;
177 static void MD5_Init(struct md5_ctx *);
178 static void MD5_Update(struct md5_ctx *, const unsigned char *, unsigned int);
179 static void MD5_Final(unsigned char [16], struct md5_ctx *);
181 /* Constants for MD5Transform routine.
201 static void MD5Transform(UINT4 [4], const unsigned char [64]);
202 static void Encode(unsigned char *, UINT4 *, unsigned int);
203 static void Decode(UINT4 *, const unsigned char *, unsigned int);
205 static const unsigned char PADDING[64] = {
206 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
207 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
208 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
211 /* F, G, H and I are basic MD5 functions.
213 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
214 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
215 #define H(x, y, z) ((x) ^ (y) ^ (z))
216 #define I(x, y, z) ((y) ^ ((x) | (~z)))
218 /* ROTATE_LEFT rotates x left n bits.
220 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
222 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
223 Rotation is separate from addition to prevent recomputation.
225 #define FF(a, b, c, d, x, s, ac) { \
226 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
227 (a) = ROTATE_LEFT ((a), (s)); \
230 #define GG(a, b, c, d, x, s, ac) { \
231 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
232 (a) = ROTATE_LEFT ((a), (s)); \
235 #define HH(a, b, c, d, x, s, ac) { \
236 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
237 (a) = ROTATE_LEFT ((a), (s)); \
240 #define II(a, b, c, d, x, s, ac) { \
241 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
242 (a) = ROTATE_LEFT ((a), (s)); \
246 /* MD5 initialization. Begins an MD5 operation, writing a new context.
248 static void MD5_Init(struct md5_ctx *context)
250 context->count[0] = context->count[1] = 0;
251 /* Load magic initialization constants. */
252 context->state[0] = 0x67452301;
253 context->state[1] = 0xefcdab89;
254 context->state[2] = 0x98badcfe;
255 context->state[3] = 0x10325476;
258 /* MD5 block update operation. Continues an MD5 message-digest
259 operation, processing another message block, and updating the
262 static void MD5_Update (struct md5_ctx *context, /* context */
263 const unsigned char *input, /* input block */
264 unsigned int inputLen) /* length of input block */
266 unsigned int i, bufindex, partLen;
268 /* Compute number of bytes mod 64 */
269 bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
271 /* Update number of bits */
272 if((context->count[0] += ((UINT4)inputLen << 3))
273 < ((UINT4)inputLen << 3))
275 context->count[1] += ((UINT4)inputLen >> 29);
277 partLen = 64 - bufindex;
279 /* Transform as many times as possible. */
280 if(inputLen >= partLen) {
281 memcpy(&context->buffer[bufindex], input, partLen);
282 MD5Transform(context->state, context->buffer);
284 for(i = partLen; i + 63 < inputLen; i += 64)
285 MD5Transform(context->state, &input[i]);
292 /* Buffer remaining input */
293 memcpy(&context->buffer[bufindex], &input[i], inputLen-i);
296 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
297 the message digest and zeroizing the context.
299 static void MD5_Final(unsigned char digest[16], /* message digest */
300 struct md5_ctx *context) /* context */
302 unsigned char bits[8];
303 unsigned int count, padLen;
305 /* Save number of bits */
306 Encode (bits, context->count, 8);
308 /* Pad out to 56 mod 64. */
309 count = (unsigned int)((context->count[0] >> 3) & 0x3f);
310 padLen = (count < 56) ? (56 - count) : (120 - count);
311 MD5_Update (context, PADDING, padLen);
313 /* Append length (before padding) */
314 MD5_Update (context, bits, 8);
316 /* Store state in digest */
317 Encode (digest, context->state, 16);
319 /* Zeroize sensitive information. */
320 memset ((void *)context, 0, sizeof (*context));
323 /* MD5 basic transformation. Transforms state based on block. */
324 static void MD5Transform(UINT4 state[4],
325 const unsigned char block[64])
327 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
329 Decode (x, block, 64);
332 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
333 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
334 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
335 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
336 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
337 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
338 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
339 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
340 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
341 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
342 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
343 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
344 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
345 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
346 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
347 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
350 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
351 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
352 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
353 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
354 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
355 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
356 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
357 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
358 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
359 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
360 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
361 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
362 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
363 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
364 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
365 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
368 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
369 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
370 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
371 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
372 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
373 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
374 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
375 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
376 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
377 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
378 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
379 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
380 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
381 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
382 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
383 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
386 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
387 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
388 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
389 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
390 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
391 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
392 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
393 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
394 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
395 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
396 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
397 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
398 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
399 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
400 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
401 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
408 /* Zeroize sensitive information. */
409 memset((void *)x, 0, sizeof (x));
412 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
415 static void Encode (unsigned char *output,
421 for(i = 0, j = 0; j < len; i++, j += 4) {
422 output[j] = (unsigned char)(input[i] & 0xff);
423 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
424 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
425 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
429 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
432 static void Decode (UINT4 *output,
433 const unsigned char *input,
438 for(i = 0, j = 0; j < len; i++, j += 4)
439 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
440 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
443 #endif /* CRYPTO LIBS */
445 /* The last #include file should be: */
446 #include "curl_memdebug.h"
448 const HMAC_params Curl_HMAC_MD5[] = {
450 (HMAC_hinit_func) MD5_Init, /* Hash initialization function. */
451 (HMAC_hupdate_func) MD5_Update, /* Hash update function. */
452 (HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */
453 sizeof(MD5_CTX), /* Size of hash context structure. */
454 64, /* Maximum key length. */
455 16 /* Result size. */
459 const MD5_params Curl_DIGEST_MD5[] = {
461 (Curl_MD5_init_func) MD5_Init, /* Digest initialization function */
462 (Curl_MD5_update_func) MD5_Update, /* Digest update function */
463 (Curl_MD5_final_func) MD5_Final, /* Digest computation end function */
464 sizeof(MD5_CTX), /* Size of digest context struct */
469 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
470 const unsigned char *input)
474 MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
475 MD5_Final(outbuffer, &ctx);
478 MD5_context *Curl_MD5_init(const MD5_params *md5params)
482 /* Create MD5 context */
483 ctxt = malloc(sizeof *ctxt);
488 ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
490 if(!ctxt->md5_hashctx) {
495 ctxt->md5_hash = md5params;
497 (*md5params->md5_init_func)(ctxt->md5_hashctx);
502 int Curl_MD5_update(MD5_context *context,
503 const unsigned char *data,
506 (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
511 int Curl_MD5_final(MD5_context *context, unsigned char *result)
513 (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
515 free(context->md5_hashctx);
521 #endif /* CURL_DISABLE_CRYPTO_AUTH */