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