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