• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 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 https://curl.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  * SPDX-License-Identifier: curl
22  *
23  ***************************************************************************/
24 
25 #include "curl_setup.h"
26 
27 #if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \
28     || !defined(CURL_DISABLE_DIGEST_AUTH)
29 
30 #include <string.h>
31 #include <curl/curl.h>
32 
33 #include "curl_md5.h"
34 #include "curl_hmac.h"
35 #include "warnless.h"
36 
37 #ifdef USE_MBEDTLS
38 #include <mbedtls/version.h>
39 
40 #if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
41    (MBEDTLS_VERSION_NUMBER < 0x03000000)
42   #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
43 #endif
44 #endif /* USE_MBEDTLS */
45 
46 #ifdef USE_OPENSSL
47   #include <openssl/opensslconf.h>
48   #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0)
49     #define USE_OPENSSL_MD5
50   #endif
51 #endif
52 
53 #ifdef USE_WOLFSSL
54   #include <wolfssl/options.h>
55   #ifndef NO_MD5
56     #define USE_WOLFSSL_MD5
57   #endif
58 #endif
59 
60 #if defined(USE_GNUTLS)
61 #include <nettle/md5.h>
62 #elif defined(USE_OPENSSL_MD5)
63 #include <openssl/md5.h>
64 #elif defined(USE_WOLFSSL_MD5)
65 #include <wolfssl/openssl/md5.h>
66 #elif defined(USE_MBEDTLS)
67 #include <mbedtls/md5.h>
68 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
69               (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
70        defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
71               (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \
72       (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
73               (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \
74        defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
75               (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000))
76 #define AN_APPLE_OS
77 #include <CommonCrypto/CommonDigest.h>
78 #elif defined(USE_WIN32_CRYPTO)
79 #include <wincrypt.h>
80 #endif
81 
82 /* The last 3 #include files should be in this order */
83 #include "curl_printf.h"
84 #include "curl_memory.h"
85 #include "memdebug.h"
86 
87 #if defined(USE_GNUTLS)
88 
89 typedef struct md5_ctx my_md5_ctx;
90 
my_md5_init(void * ctx)91 static CURLcode my_md5_init(void *ctx)
92 {
93   md5_init(ctx);
94   return CURLE_OK;
95 }
96 
my_md5_update(void * ctx,const unsigned char * input,unsigned int inputLen)97 static void my_md5_update(void *ctx,
98                           const unsigned char *input,
99                           unsigned int inputLen)
100 {
101   md5_update(ctx, inputLen, input);
102 }
103 
my_md5_final(unsigned char * digest,void * ctx)104 static void my_md5_final(unsigned char *digest, void *ctx)
105 {
106   md5_digest(ctx, 16, digest);
107 }
108 
109 #elif defined(USE_OPENSSL_MD5) || \
110   (defined(USE_WOLFSSL_MD5) && !defined(OPENSSL_COEXIST))
111 
112 typedef MD5_CTX my_md5_ctx;
113 
my_md5_init(void * ctx)114 static CURLcode my_md5_init(void *ctx)
115 {
116   if(!MD5_Init(ctx))
117     return CURLE_OUT_OF_MEMORY;
118 
119   return CURLE_OK;
120 }
121 
my_md5_update(void * ctx,const unsigned char * input,unsigned int len)122 static void my_md5_update(void *ctx,
123                           const unsigned char *input,
124                           unsigned int len)
125 {
126   (void)MD5_Update(ctx, input, len);
127 }
128 
my_md5_final(unsigned char * digest,void * ctx)129 static void my_md5_final(unsigned char *digest, void *ctx)
130 {
131   (void)MD5_Final(digest, ctx);
132 }
133 
134 #elif defined(USE_WOLFSSL_MD5)
135 
136 typedef WOLFSSL_MD5_CTX my_md5_ctx;
137 
my_md5_init(void * ctx)138 static CURLcode my_md5_init(void *ctx)
139 {
140   if(!wolfSSL_MD5_Init(ctx))
141     return CURLE_OUT_OF_MEMORY;
142 
143   return CURLE_OK;
144 }
145 
my_md5_update(void * ctx,const unsigned char * input,unsigned int len)146 static void my_md5_update(void *ctx,
147                           const unsigned char *input,
148                           unsigned int len)
149 {
150   (void)wolfSSL_MD5_Update(ctx, input, len);
151 }
152 
my_md5_final(unsigned char * digest,void * ctx)153 static void my_md5_final(unsigned char *digest, void *ctx)
154 {
155   (void)wolfSSL_MD5_Final(digest, ctx);
156 }
157 
158 #elif defined(USE_MBEDTLS)
159 
160 typedef mbedtls_md5_context my_md5_ctx;
161 
my_md5_init(void * ctx)162 static CURLcode my_md5_init(void *ctx)
163 {
164 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
165   if(mbedtls_md5_starts(ctx))
166     return CURLE_OUT_OF_MEMORY;
167 #elif defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
168   if(mbedtls_md5_starts_ret(ctx))
169     return CURLE_OUT_OF_MEMORY;
170 #else
171   (void)mbedtls_md5_starts(ctx);
172 #endif
173   return CURLE_OK;
174 }
175 
my_md5_update(void * ctx,const unsigned char * data,unsigned int length)176 static void my_md5_update(void *ctx,
177                           const unsigned char *data,
178                           unsigned int length)
179 {
180 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
181   (void) mbedtls_md5_update(ctx, data, length);
182 #else
183   (void) mbedtls_md5_update_ret(ctx, data, length);
184 #endif
185 }
186 
my_md5_final(unsigned char * digest,void * ctx)187 static void my_md5_final(unsigned char *digest, void *ctx)
188 {
189 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
190   (void) mbedtls_md5_finish(ctx, digest);
191 #else
192   (void) mbedtls_md5_finish_ret(ctx, digest);
193 #endif
194 }
195 
196 #elif defined(AN_APPLE_OS)
197 
198 /* For Apple operating systems: CommonCrypto has the functions we need.
199    These functions are available on Tiger and later, as well as iOS 2.0
200    and later. If you are building for an older cat, well, sorry.
201 
202    Declaring the functions as static like this seems to be a bit more
203    reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
204 #  define my_md5_ctx CC_MD5_CTX
205 
my_md5_init(void * ctx)206 static CURLcode my_md5_init(void *ctx)
207 {
208   if(!CC_MD5_Init(ctx))
209     return CURLE_OUT_OF_MEMORY;
210 
211   return CURLE_OK;
212 }
213 
my_md5_update(void * ctx,const unsigned char * input,unsigned int inputLen)214 static void my_md5_update(void *ctx,
215                           const unsigned char *input,
216                           unsigned int inputLen)
217 {
218   CC_MD5_Update(ctx, input, inputLen);
219 }
220 
my_md5_final(unsigned char * digest,void * ctx)221 static void my_md5_final(unsigned char *digest, void *ctx)
222 {
223   CC_MD5_Final(digest, ctx);
224 }
225 
226 #elif defined(USE_WIN32_CRYPTO)
227 
228 struct md5_ctx {
229   HCRYPTPROV hCryptProv;
230   HCRYPTHASH hHash;
231 };
232 typedef struct md5_ctx my_md5_ctx;
233 
my_md5_init(void * in)234 static CURLcode my_md5_init(void *in)
235 {
236   my_md5_ctx *ctx = (my_md5_ctx *)in;
237   if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
238                           CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
239     return CURLE_OUT_OF_MEMORY;
240 
241   if(!CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash)) {
242     CryptReleaseContext(ctx->hCryptProv, 0);
243     ctx->hCryptProv = 0;
244     return CURLE_FAILED_INIT;
245   }
246 
247   return CURLE_OK;
248 }
249 
my_md5_update(void * in,const unsigned char * input,unsigned int inputLen)250 static void my_md5_update(void *in,
251                           const unsigned char *input,
252                           unsigned int inputLen)
253 {
254   my_md5_ctx *ctx = in;
255   CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
256 }
257 
my_md5_final(unsigned char * digest,void * in)258 static void my_md5_final(unsigned char *digest, void *in)
259 {
260   my_md5_ctx *ctx = (my_md5_ctx *)in;
261   unsigned long length = 0;
262   CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
263   if(length == 16)
264     CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
265   if(ctx->hHash)
266     CryptDestroyHash(ctx->hHash);
267   if(ctx->hCryptProv)
268     CryptReleaseContext(ctx->hCryptProv, 0);
269 }
270 
271 #else
272 
273 /* When no other crypto library is available we use this code segment */
274 
275 /*
276  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
277  * MD5 Message-Digest Algorithm (RFC 1321).
278  *
279  * Homepage:
280  https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
281  *
282  * Author:
283  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
284  *
285  * This software was written by Alexander Peslyak in 2001. No copyright is
286  * claimed, and the software is hereby placed in the public domain.
287  * In case this attempt to disclaim copyright and place the software in the
288  * public domain is deemed null and void, then the software is
289  * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
290  * general public under the following terms:
291  *
292  * Redistribution and use in source and binary forms, with or without
293  * modification, are permitted.
294  *
295  * There is ABSOLUTELY NO WARRANTY, express or implied.
296  *
297  * (This is a heavily cut-down "BSD license".)
298  *
299  * This differs from Colin Plumb's older public domain implementation in that
300  * no exactly 32-bit integer data type is required (any 32-bit or wider
301  * unsigned integer data type will do), there is no compile-time endianness
302  * configuration, and the function prototypes match OpenSSL's. No code from
303  * Colin Plumb's implementation has been reused; this comment merely compares
304  * the properties of the two independent implementations.
305  *
306  * The primary goals of this implementation are portability and ease of use.
307  * It is meant to be fast, but not as fast as possible. Some known
308  * optimizations are not included to reduce source code size and avoid
309  * compile-time configuration.
310  */
311 
312 /* Any 32-bit or wider unsigned integer data type will do */
313 typedef unsigned int MD5_u32plus;
314 
315 struct md5_ctx {
316   MD5_u32plus lo, hi;
317   MD5_u32plus a, b, c, d;
318   unsigned char buffer[64];
319   MD5_u32plus block[16];
320 };
321 typedef struct md5_ctx my_md5_ctx;
322 
323 static CURLcode my_md5_init(void *ctx);
324 static void my_md5_update(void *ctx, const unsigned char *data,
325                           unsigned int size);
326 static void my_md5_final(unsigned char *result, void *ctx);
327 
328 /*
329  * The basic MD5 functions.
330  *
331  * F and G are optimized compared to their RFC 1321 definitions for
332  * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
333  * implementation.
334  */
335 #define MD5_F(x, y, z)                  ((z) ^ ((x) & ((y) ^ (z))))
336 #define MD5_G(x, y, z)                  ((y) ^ ((z) & ((x) ^ (y))))
337 #define MD5_H(x, y, z)                  (((x) ^ (y)) ^ (z))
338 #define MD5_H2(x, y, z)                 ((x) ^ ((y) ^ (z)))
339 #define MD5_I(x, y, z)                  ((y) ^ ((x) | ~(z)))
340 
341 /*
342  * The MD5 transformation for all four rounds.
343  */
344 #define MD5_STEP(f, a, b, c, d, x, t, s) \
345         (a) += f((b), (c), (d)) + (x) + (t); \
346         (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
347         (a) += (b);
348 
349 /*
350  * SET reads 4 input bytes in little-endian byte order and stores them
351  * in a properly aligned word in host byte order.
352  *
353  * The check for little-endian architectures that tolerate unaligned
354  * memory accesses is just an optimization. Nothing will break if it
355  * does not work.
356  */
357 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
358 #define MD5_SET(n) \
359         (*(MD5_u32plus *)(void *)&ptr[(n) * 4])
360 #define MD5_GET(n) \
361         MD5_SET(n)
362 #else
363 #define MD5_SET(n) \
364         (ctx->block[(n)] = \
365         (MD5_u32plus)ptr[(n) * 4] | \
366         ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
367         ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
368         ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
369 #define MD5_GET(n) \
370         (ctx->block[(n)])
371 #endif
372 
373 /*
374  * This processes one or more 64-byte data blocks, but does NOT update
375  * the bit counters. There are no alignment requirements.
376  */
my_md5_body(my_md5_ctx * ctx,const void * data,unsigned long size)377 static const void *my_md5_body(my_md5_ctx *ctx,
378                                const void *data, unsigned long size)
379 {
380   const unsigned char *ptr;
381   MD5_u32plus a, b, c, d;
382 
383   ptr = (const unsigned char *)data;
384 
385   a = ctx->a;
386   b = ctx->b;
387   c = ctx->c;
388   d = ctx->d;
389 
390   do {
391     MD5_u32plus saved_a, saved_b, saved_c, saved_d;
392 
393     saved_a = a;
394     saved_b = b;
395     saved_c = c;
396     saved_d = d;
397 
398 /* Round 1 */
399     MD5_STEP(MD5_F, a, b, c, d, MD5_SET(0), 0xd76aa478, 7)
400     MD5_STEP(MD5_F, d, a, b, c, MD5_SET(1), 0xe8c7b756, 12)
401     MD5_STEP(MD5_F, c, d, a, b, MD5_SET(2), 0x242070db, 17)
402     MD5_STEP(MD5_F, b, c, d, a, MD5_SET(3), 0xc1bdceee, 22)
403     MD5_STEP(MD5_F, a, b, c, d, MD5_SET(4), 0xf57c0faf, 7)
404     MD5_STEP(MD5_F, d, a, b, c, MD5_SET(5), 0x4787c62a, 12)
405     MD5_STEP(MD5_F, c, d, a, b, MD5_SET(6), 0xa8304613, 17)
406     MD5_STEP(MD5_F, b, c, d, a, MD5_SET(7), 0xfd469501, 22)
407     MD5_STEP(MD5_F, a, b, c, d, MD5_SET(8), 0x698098d8, 7)
408     MD5_STEP(MD5_F, d, a, b, c, MD5_SET(9), 0x8b44f7af, 12)
409     MD5_STEP(MD5_F, c, d, a, b, MD5_SET(10), 0xffff5bb1, 17)
410     MD5_STEP(MD5_F, b, c, d, a, MD5_SET(11), 0x895cd7be, 22)
411     MD5_STEP(MD5_F, a, b, c, d, MD5_SET(12), 0x6b901122, 7)
412     MD5_STEP(MD5_F, d, a, b, c, MD5_SET(13), 0xfd987193, 12)
413     MD5_STEP(MD5_F, c, d, a, b, MD5_SET(14), 0xa679438e, 17)
414     MD5_STEP(MD5_F, b, c, d, a, MD5_SET(15), 0x49b40821, 22)
415 
416 /* Round 2 */
417     MD5_STEP(MD5_G, a, b, c, d, MD5_GET(1), 0xf61e2562, 5)
418     MD5_STEP(MD5_G, d, a, b, c, MD5_GET(6), 0xc040b340, 9)
419     MD5_STEP(MD5_G, c, d, a, b, MD5_GET(11), 0x265e5a51, 14)
420     MD5_STEP(MD5_G, b, c, d, a, MD5_GET(0), 0xe9b6c7aa, 20)
421     MD5_STEP(MD5_G, a, b, c, d, MD5_GET(5), 0xd62f105d, 5)
422     MD5_STEP(MD5_G, d, a, b, c, MD5_GET(10), 0x02441453, 9)
423     MD5_STEP(MD5_G, c, d, a, b, MD5_GET(15), 0xd8a1e681, 14)
424     MD5_STEP(MD5_G, b, c, d, a, MD5_GET(4), 0xe7d3fbc8, 20)
425     MD5_STEP(MD5_G, a, b, c, d, MD5_GET(9), 0x21e1cde6, 5)
426     MD5_STEP(MD5_G, d, a, b, c, MD5_GET(14), 0xc33707d6, 9)
427     MD5_STEP(MD5_G, c, d, a, b, MD5_GET(3), 0xf4d50d87, 14)
428     MD5_STEP(MD5_G, b, c, d, a, MD5_GET(8), 0x455a14ed, 20)
429     MD5_STEP(MD5_G, a, b, c, d, MD5_GET(13), 0xa9e3e905, 5)
430     MD5_STEP(MD5_G, d, a, b, c, MD5_GET(2), 0xfcefa3f8, 9)
431     MD5_STEP(MD5_G, c, d, a, b, MD5_GET(7), 0x676f02d9, 14)
432     MD5_STEP(MD5_G, b, c, d, a, MD5_GET(12), 0x8d2a4c8a, 20)
433 
434 /* Round 3 */
435     MD5_STEP(MD5_H, a, b, c, d, MD5_GET(5), 0xfffa3942, 4)
436     MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(8), 0x8771f681, 11)
437     MD5_STEP(MD5_H, c, d, a, b, MD5_GET(11), 0x6d9d6122, 16)
438     MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(14), 0xfde5380c, 23)
439     MD5_STEP(MD5_H, a, b, c, d, MD5_GET(1), 0xa4beea44, 4)
440     MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(4), 0x4bdecfa9, 11)
441     MD5_STEP(MD5_H, c, d, a, b, MD5_GET(7), 0xf6bb4b60, 16)
442     MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(10), 0xbebfbc70, 23)
443     MD5_STEP(MD5_H, a, b, c, d, MD5_GET(13), 0x289b7ec6, 4)
444     MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(0), 0xeaa127fa, 11)
445     MD5_STEP(MD5_H, c, d, a, b, MD5_GET(3), 0xd4ef3085, 16)
446     MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(6), 0x04881d05, 23)
447     MD5_STEP(MD5_H, a, b, c, d, MD5_GET(9), 0xd9d4d039, 4)
448     MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(12), 0xe6db99e5, 11)
449     MD5_STEP(MD5_H, c, d, a, b, MD5_GET(15), 0x1fa27cf8, 16)
450     MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(2), 0xc4ac5665, 23)
451 
452 /* Round 4 */
453     MD5_STEP(MD5_I, a, b, c, d, MD5_GET(0), 0xf4292244, 6)
454     MD5_STEP(MD5_I, d, a, b, c, MD5_GET(7), 0x432aff97, 10)
455     MD5_STEP(MD5_I, c, d, a, b, MD5_GET(14), 0xab9423a7, 15)
456     MD5_STEP(MD5_I, b, c, d, a, MD5_GET(5), 0xfc93a039, 21)
457     MD5_STEP(MD5_I, a, b, c, d, MD5_GET(12), 0x655b59c3, 6)
458     MD5_STEP(MD5_I, d, a, b, c, MD5_GET(3), 0x8f0ccc92, 10)
459     MD5_STEP(MD5_I, c, d, a, b, MD5_GET(10), 0xffeff47d, 15)
460     MD5_STEP(MD5_I, b, c, d, a, MD5_GET(1), 0x85845dd1, 21)
461     MD5_STEP(MD5_I, a, b, c, d, MD5_GET(8), 0x6fa87e4f, 6)
462     MD5_STEP(MD5_I, d, a, b, c, MD5_GET(15), 0xfe2ce6e0, 10)
463     MD5_STEP(MD5_I, c, d, a, b, MD5_GET(6), 0xa3014314, 15)
464     MD5_STEP(MD5_I, b, c, d, a, MD5_GET(13), 0x4e0811a1, 21)
465     MD5_STEP(MD5_I, a, b, c, d, MD5_GET(4), 0xf7537e82, 6)
466     MD5_STEP(MD5_I, d, a, b, c, MD5_GET(11), 0xbd3af235, 10)
467     MD5_STEP(MD5_I, c, d, a, b, MD5_GET(2), 0x2ad7d2bb, 15)
468     MD5_STEP(MD5_I, b, c, d, a, MD5_GET(9), 0xeb86d391, 21)
469 
470     a += saved_a;
471     b += saved_b;
472     c += saved_c;
473     d += saved_d;
474 
475     ptr += 64;
476   } while(size -= 64);
477 
478   ctx->a = a;
479   ctx->b = b;
480   ctx->c = c;
481   ctx->d = d;
482 
483   return ptr;
484 }
485 
my_md5_init(void * in)486 static CURLcode my_md5_init(void *in)
487 {
488   my_md5_ctx *ctx = (my_md5_ctx *)in;
489   ctx->a = 0x67452301;
490   ctx->b = 0xefcdab89;
491   ctx->c = 0x98badcfe;
492   ctx->d = 0x10325476;
493 
494   ctx->lo = 0;
495   ctx->hi = 0;
496 
497   return CURLE_OK;
498 }
499 
my_md5_update(void * in,const unsigned char * data,unsigned int size)500 static void my_md5_update(void *in, const unsigned char *data,
501                           unsigned int size)
502 {
503   MD5_u32plus saved_lo;
504   unsigned int used;
505   my_md5_ctx *ctx = (my_md5_ctx *)in;
506 
507   saved_lo = ctx->lo;
508   ctx->lo = (saved_lo + size) & 0x1fffffff;
509   if(ctx->lo < saved_lo)
510     ctx->hi++;
511   ctx->hi += (MD5_u32plus)size >> 29;
512 
513   used = saved_lo & 0x3f;
514 
515   if(used) {
516     unsigned int available = 64 - used;
517 
518     if(size < available) {
519       memcpy(&ctx->buffer[used], data, size);
520       return;
521     }
522 
523     memcpy(&ctx->buffer[used], data, available);
524     data = (const unsigned char *)data + available;
525     size -= available;
526     my_md5_body(ctx, ctx->buffer, 64);
527   }
528 
529   if(size >= 64) {
530     data = my_md5_body(ctx, data, size & ~(unsigned long)0x3f);
531     size &= 0x3f;
532   }
533 
534   memcpy(ctx->buffer, data, size);
535 }
536 
my_md5_final(unsigned char * result,void * in)537 static void my_md5_final(unsigned char *result, void *in)
538 {
539   unsigned int used, available;
540   my_md5_ctx *ctx = (my_md5_ctx *)in;
541 
542   used = ctx->lo & 0x3f;
543 
544   ctx->buffer[used++] = 0x80;
545 
546   available = 64 - used;
547 
548   if(available < 8) {
549     memset(&ctx->buffer[used], 0, available);
550     my_md5_body(ctx, ctx->buffer, 64);
551     used = 0;
552     available = 64;
553   }
554 
555   memset(&ctx->buffer[used], 0, available - 8);
556 
557   ctx->lo <<= 3;
558   ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
559   ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
560   ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
561   ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
562   ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
563   ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
564   ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
565   ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
566 
567   my_md5_body(ctx, ctx->buffer, 64);
568 
569   result[0] = curlx_ultouc((ctx->a)&0xff);
570   result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
571   result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
572   result[3] = curlx_ultouc(ctx->a >> 24);
573   result[4] = curlx_ultouc((ctx->b)&0xff);
574   result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
575   result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
576   result[7] = curlx_ultouc(ctx->b >> 24);
577   result[8] = curlx_ultouc((ctx->c)&0xff);
578   result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
579   result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
580   result[11] = curlx_ultouc(ctx->c >> 24);
581   result[12] = curlx_ultouc((ctx->d)&0xff);
582   result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
583   result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
584   result[15] = curlx_ultouc(ctx->d >> 24);
585 
586   memset(ctx, 0, sizeof(*ctx));
587 }
588 
589 #endif /* CRYPTO LIBS */
590 
591 const struct HMAC_params Curl_HMAC_MD5 = {
592   my_md5_init,        /* Hash initialization function. */
593   my_md5_update,      /* Hash update function. */
594   my_md5_final,       /* Hash computation end function. */
595   sizeof(my_md5_ctx), /* Size of hash context structure. */
596   64,                 /* Maximum key length. */
597   16                  /* Result size. */
598 };
599 
600 const struct MD5_params Curl_DIGEST_MD5 = {
601   my_md5_init,        /* Digest initialization function */
602   my_md5_update,      /* Digest update function */
603   my_md5_final,       /* Digest computation end function */
604   sizeof(my_md5_ctx), /* Size of digest context struct */
605   16                  /* Result size */
606 };
607 
608 /*
609  * @unittest: 1601
610  * Returns CURLE_OK on success.
611  */
Curl_md5it(unsigned char * outbuffer,const unsigned char * input,const size_t len)612 CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
613                     const size_t len)
614 {
615   CURLcode result;
616   my_md5_ctx ctx;
617 
618   result = my_md5_init(&ctx);
619   if(!result) {
620     my_md5_update(&ctx, input, curlx_uztoui(len));
621     my_md5_final(outbuffer, &ctx);
622   }
623   return result;
624 }
625 
Curl_MD5_init(const struct MD5_params * md5params)626 struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
627 {
628   struct MD5_context *ctxt;
629 
630   /* Create MD5 context */
631   ctxt = malloc(sizeof(*ctxt));
632 
633   if(!ctxt)
634     return ctxt;
635 
636   ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
637 
638   if(!ctxt->md5_hashctx) {
639     free(ctxt);
640     return NULL;
641   }
642 
643   ctxt->md5_hash = md5params;
644 
645   if((*md5params->md5_init_func)(ctxt->md5_hashctx)) {
646     free(ctxt->md5_hashctx);
647     free(ctxt);
648     return NULL;
649   }
650 
651   return ctxt;
652 }
653 
Curl_MD5_update(struct MD5_context * context,const unsigned char * data,unsigned int len)654 CURLcode Curl_MD5_update(struct MD5_context *context,
655                          const unsigned char *data,
656                          unsigned int len)
657 {
658   (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
659 
660   return CURLE_OK;
661 }
662 
Curl_MD5_final(struct MD5_context * context,unsigned char * result)663 CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result)
664 {
665   (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
666 
667   free(context->md5_hashctx);
668   free(context);
669 
670   return CURLE_OK;
671 }
672 
673 #endif /* Using NTLM (without SSPI) || Digest */
674