Coverage Report

Created: 2024-05-04 12:45

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