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