1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
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.
13  *
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.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * $Id: md5.c,v 1.15 2009-02-12 20:48:44 danf Exp $
22  ***************************************************************************/
23 
24 #include "setup.h"
25 
26 #ifndef CURL_DISABLE_CRYPTO_AUTH
27 
28 #include <string.h>
29 
30 #include "curl_md5.h"
31 
32 #ifdef USE_GNUTLS
33 
34 #include <gcrypt.h>
35 
Curl_md5it(unsigned char * outbuffer,const unsigned char * input)36 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
37                 const unsigned char *input)
38 {
39   gcry_md_hd_t ctx;
40   gcry_md_open(&ctx, GCRY_MD_MD5, 0);
41   gcry_md_write(ctx, input, (unsigned int)strlen((char *)input));
42   memcpy (outbuffer, gcry_md_read (ctx, 0), 16);
43   gcry_md_close(ctx);
44 }
45 
46 #else
47 
48 #ifdef USE_SSLEAY
49 /* When OpenSSL is available we use the MD5-function from OpenSSL */
50 
51 #  ifdef USE_OPENSSL
52 #    include <openssl/md5.h>
53 #  else
54 #    include <md5.h>
55 #  endif
56 
57 #else /* USE_SSLEAY */
58 /* When OpenSSL is not available we use this code segment */
59 
60 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
61 rights reserved.
62 
63 License to copy and use this software is granted provided that it
64 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
65 Algorithm" in all material mentioning or referencing this software
66 or this function.
67 
68 License is also granted to make and use derivative works provided
69 that such works are identified as "derived from the RSA Data
70 Security, Inc. MD5 Message-Digest Algorithm" in all material
71 mentioning or referencing the derived work.
72 
73 RSA Data Security, Inc. makes no representations concerning either
74 the merchantability of this software or the suitability of this
75 software for any particular purpose. It is provided "as is"
76 without express or implied warranty of any kind.
77 
78 These notices must be retained in any copies of any part of this
79 documentation and/or software.
80  */
81 
82 /* UINT4 defines a four byte word */
83 typedef unsigned int UINT4;
84 
85 /* MD5 context. */
86 struct md5_ctx {
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 };
91 
92 typedef struct md5_ctx MD5_CTX;
93 
94 static void MD5_Init(struct md5_ctx *);
95 static void MD5_Update(struct md5_ctx *, const unsigned char *, unsigned int);
96 static void MD5_Final(unsigned char [16], struct md5_ctx *);
97 
98 /* Constants for MD5Transform routine.
99  */
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 static void MD5Transform(UINT4 [4], const unsigned char [64]);
119 static void Encode(unsigned char *, UINT4 *, unsigned int);
120 static void Decode(UINT4 *, const unsigned char *, unsigned int);
121 
122 static const unsigned char PADDING[64] = {
123   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
125   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
126 };
127 
128 /* F, G, H and I are basic MD5 functions.
129  */
130 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
131 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
132 #define H(x, y, z) ((x) ^ (y) ^ (z))
133 #define I(x, y, z) ((y) ^ ((x) | (~z)))
134 
135 /* ROTATE_LEFT rotates x left n bits.
136  */
137 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
138 
139 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
140 Rotation is separate from addition to prevent recomputation.
141  */
142 #define FF(a, b, c, d, x, s, ac) { \
143  (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
144  (a) = ROTATE_LEFT ((a), (s)); \
145  (a) += (b); \
146   }
147 #define GG(a, b, c, d, x, s, ac) { \
148  (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
149  (a) = ROTATE_LEFT ((a), (s)); \
150  (a) += (b); \
151   }
152 #define HH(a, b, c, d, x, s, ac) { \
153  (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
154  (a) = ROTATE_LEFT ((a), (s)); \
155  (a) += (b); \
156   }
157 #define II(a, b, c, d, x, s, ac) { \
158  (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
159  (a) = ROTATE_LEFT ((a), (s)); \
160  (a) += (b); \
161   }
162 
163 /* MD5 initialization. Begins an MD5 operation, writing a new context.
164  */
MD5_Init(struct md5_ctx * context)165 static void MD5_Init(struct md5_ctx *context)
166 {
167   context->count[0] = context->count[1] = 0;
168   /* Load magic initialization constants. */
169   context->state[0] = 0x67452301;
170   context->state[1] = 0xefcdab89;
171   context->state[2] = 0x98badcfe;
172   context->state[3] = 0x10325476;
173 }
174 
175 /* MD5 block update operation. Continues an MD5 message-digest
176   operation, processing another message block, and updating the
177   context.
178  */
MD5_Update(struct md5_ctx * context,const unsigned char * input,unsigned int inputLen)179 static void MD5_Update (struct md5_ctx *context,    /* context */
180                         const unsigned char *input, /* input block */
181                         unsigned int inputLen)      /* length of input block */
182 {
183   unsigned int i, bufindex, partLen;
184 
185   /* Compute number of bytes mod 64 */
186   bufindex = (unsigned int)((context->count[0] >> 3) & 0x3F);
187 
188   /* Update number of bits */
189   if((context->count[0] += ((UINT4)inputLen << 3))
190       < ((UINT4)inputLen << 3))
191     context->count[1]++;
192   context->count[1] += ((UINT4)inputLen >> 29);
193 
194   partLen = 64 - bufindex;
195 
196   /* Transform as many times as possible. */
197   if(inputLen >= partLen) {
198     memcpy((void *)&context->buffer[bufindex], (void *)input, partLen);
199     MD5Transform(context->state, context->buffer);
200 
201     for (i = partLen; i + 63 < inputLen; i += 64)
202       MD5Transform(context->state, &input[i]);
203 
204     bufindex = 0;
205   }
206   else
207     i = 0;
208 
209   /* Buffer remaining input */
210   memcpy((void *)&context->buffer[bufindex], (void *)&input[i], inputLen-i);
211 }
212 
213 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
214    the message digest and zeroizing the context.
215 */
MD5_Final(unsigned char digest[16],struct md5_ctx * context)216 static void MD5_Final(unsigned char digest[16], /* message digest */
217                       struct md5_ctx *context) /* context */
218 {
219   unsigned char bits[8];
220   unsigned int count, padLen;
221 
222   /* Save number of bits */
223   Encode (bits, context->count, 8);
224 
225   /* Pad out to 56 mod 64. */
226   count = (unsigned int)((context->count[0] >> 3) & 0x3f);
227   padLen = (count < 56) ? (56 - count) : (120 - count);
228   MD5_Update (context, PADDING, padLen);
229 
230   /* Append length (before padding) */
231   MD5_Update (context, bits, 8);
232 
233   /* Store state in digest */
234   Encode (digest, context->state, 16);
235 
236   /* Zeroize sensitive information. */
237   memset ((void *)context, 0, sizeof (*context));
238 }
239 
240 /* MD5 basic transformation. Transforms state based on block. */
MD5Transform(UINT4 state[4],const unsigned char block[64])241 static void MD5Transform(UINT4 state[4],
242                          const unsigned char block[64])
243 {
244   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
245 
246   Decode (x, block, 64);
247 
248   /* Round 1 */
249   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
250   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
251   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
252   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
253   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
254   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
255   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
256   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
257   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
258   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
259   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
260   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
261   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
262   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
263   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
264   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
265 
266  /* Round 2 */
267   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
268   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
269   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
270   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
271   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
272   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
273   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
274   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
275   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
276   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
277   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
278   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
279   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
280   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
281   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
282   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
283 
284   /* Round 3 */
285   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
286   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
287   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
288   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
289   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
290   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
291   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
292   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
293   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
294   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
295   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
296   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
297   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
298   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
299   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
300   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
301 
302   /* Round 4 */
303   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
304   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
305   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
306   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
307   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
308   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
309   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
310   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
311   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
312   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
313   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
314   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
315   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
316   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
317   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
318   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
319 
320   state[0] += a;
321   state[1] += b;
322   state[2] += c;
323   state[3] += d;
324 
325   /* Zeroize sensitive information. */
326   memset((void *)x, 0, sizeof (x));
327 }
328 
329 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
330   a multiple of 4.
331  */
Encode(unsigned char * output,UINT4 * input,unsigned int len)332 static void Encode (unsigned char *output,
333                     UINT4 *input,
334                     unsigned int len)
335 {
336   unsigned int i, j;
337 
338   for (i = 0, j = 0; j < len; i++, j += 4) {
339     output[j] = (unsigned char)(input[i] & 0xff);
340     output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
341     output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
342     output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
343   }
344 }
345 
346 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
347    a multiple of 4.
348 */
Decode(UINT4 * output,const unsigned char * input,unsigned int len)349 static void Decode (UINT4 *output,
350                     const unsigned char *input,
351                     unsigned int len)
352 {
353   unsigned int i, j;
354 
355   for (i = 0, j = 0; j < len; i++, j += 4)
356     output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
357       (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
358 }
359 
360 #endif /* USE_SSLEAY */
361 
Curl_md5it(unsigned char * outbuffer,const unsigned char * input)362 void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
363                 const unsigned char *input)
364 {
365   MD5_CTX ctx;
366   MD5_Init(&ctx);
367   MD5_Update(&ctx, input, (unsigned int)strlen((char *)input));
368   MD5_Final(outbuffer, &ctx);
369 }
370 
371 #endif /* USE_GNUTLS */
372 
373 #endif /* CURL_DISABLE_CRYPTO_AUTH */
374