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