Coverage Report

Created: 2026-04-29 07:01

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