Coverage Report

Created: 2024-02-25 06:14

/src/PROJ/curl/lib/md4.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)
28
29
#include <string.h>
30
31
#include "strdup.h"
32
#include "curl_md4.h"
33
#include "warnless.h"
34
35
#ifdef USE_OPENSSL
36
#include <openssl/opensslv.h>
37
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) && !defined(USE_AMISSL)
38
/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
39
#define OPENSSL_NO_MD4
40
#endif
41
#endif /* USE_OPENSSL */
42
43
#ifdef USE_WOLFSSL
44
#include <wolfssl/options.h>
45
#define VOID_MD4_INIT
46
#ifdef NO_MD4
47
#define WOLFSSL_NO_MD4
48
#endif
49
#endif
50
51
#ifdef USE_MBEDTLS
52
#include <mbedtls/version.h>
53
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
54
#include <mbedtls/mbedtls_config.h>
55
#else
56
#include <mbedtls/config.h>
57
#endif
58
#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
59
  #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
60
#endif
61
#endif /* USE_MBEDTLS */
62
63
#if defined(USE_GNUTLS)
64
#include <nettle/md4.h>
65
/* When OpenSSL or wolfSSL is available, we use their MD4 functions. */
66
#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
67
#include <wolfssl/openssl/md4.h>
68
#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
69
#include <openssl/md4.h>
70
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
71
              (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
72
       defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
73
              (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \
74
      (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
75
              (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \
76
       defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
77
              (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000))
78
#define AN_APPLE_OS
79
#include <CommonCrypto/CommonDigest.h>
80
#elif defined(USE_WIN32_CRYPTO)
81
#include <wincrypt.h>
82
#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
83
#include <mbedtls/md4.h>
84
#endif
85
86
/* The last 3 #include files should be in this order */
87
#include "curl_printf.h"
88
#include "curl_memory.h"
89
#include "memdebug.h"
90
91
92
#if defined(USE_GNUTLS)
93
94
typedef struct md4_ctx MD4_CTX;
95
96
static int MD4_Init(MD4_CTX *ctx)
97
{
98
  md4_init(ctx);
99
  return 1;
100
}
101
102
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
103
{
104
  md4_update(ctx, size, data);
105
}
106
107
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
108
{
109
  md4_digest(ctx, MD4_DIGEST_SIZE, result);
110
}
111
112
#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
113
114
#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
115
116
#elif defined(AN_APPLE_OS)
117
typedef CC_MD4_CTX MD4_CTX;
118
119
static int MD4_Init(MD4_CTX *ctx)
120
{
121
  return CC_MD4_Init(ctx);
122
}
123
124
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
125
{
126
  (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
127
}
128
129
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
130
{
131
  (void)CC_MD4_Final(result, ctx);
132
}
133
134
#elif defined(USE_WIN32_CRYPTO)
135
136
struct md4_ctx {
137
  HCRYPTPROV hCryptProv;
138
  HCRYPTHASH hHash;
139
};
140
typedef struct md4_ctx MD4_CTX;
141
142
static int MD4_Init(MD4_CTX *ctx)
143
{
144
  ctx->hCryptProv = 0;
145
  ctx->hHash = 0;
146
147
  if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
148
                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
149
    return 0;
150
151
  if(!CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash)) {
152
    CryptReleaseContext(ctx->hCryptProv, 0);
153
    ctx->hCryptProv = 0;
154
    return 0;
155
  }
156
157
  return 1;
158
}
159
160
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
161
{
162
  CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
163
}
164
165
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
166
{
167
  unsigned long length = 0;
168
169
  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
170
  if(length == MD4_DIGEST_LENGTH)
171
    CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
172
173
  if(ctx->hHash)
174
    CryptDestroyHash(ctx->hHash);
175
176
  if(ctx->hCryptProv)
177
    CryptReleaseContext(ctx->hCryptProv, 0);
178
}
179
180
#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
181
182
struct md4_ctx {
183
  void *data;
184
  unsigned long size;
185
};
186
typedef struct md4_ctx MD4_CTX;
187
188
static int MD4_Init(MD4_CTX *ctx)
189
{
190
  ctx->data = NULL;
191
  ctx->size = 0;
192
  return 1;
193
}
194
195
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
196
{
197
  if(!ctx->data) {
198
    ctx->data = Curl_memdup(data, size);
199
    if(ctx->data)
200
      ctx->size = size;
201
  }
202
}
203
204
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
205
{
206
  if(ctx->data) {
207
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
208
    mbedtls_md4(ctx->data, ctx->size, result);
209
#else
210
    (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
211
#endif
212
213
    Curl_safefree(ctx->data);
214
    ctx->size = 0;
215
  }
216
}
217
218
#else
219
/* When no other crypto library is available, or the crypto library doesn't
220
 * support MD4, we use this code segment this implementation of it
221
 *
222
 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
223
 * MD4 Message-Digest Algorithm (RFC 1320).
224
 *
225
 * Homepage:
226
 https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
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.  In case
233
 * this attempt to disclaim copyright and place the software in the public
234
 * domain is deemed null and void, then the software is Copyright (c) 2001
235
 * Alexander Peslyak and it is hereby released to the general public under the
236
 * 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
/* Any 32-bit or wider unsigned integer data type will do */
259
typedef unsigned int MD4_u32plus;
260
261
struct md4_ctx {
262
  MD4_u32plus lo, hi;
263
  MD4_u32plus a, b, c, d;
264
  unsigned char buffer[64];
265
  MD4_u32plus block[16];
266
};
267
typedef struct md4_ctx MD4_CTX;
268
269
static int MD4_Init(MD4_CTX *ctx);
270
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
271
static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
272
273
/*
274
 * The basic MD4 functions.
275
 *
276
 * F and G are optimized compared to their RFC 1320 definitions, with the
277
 * optimization for F borrowed from Colin Plumb's MD5 implementation.
278
 */
279
#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
280
#define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
281
#define H(x, y, z)                      ((x) ^ (y) ^ (z))
282
283
/*
284
 * The MD4 transformation for all three rounds.
285
 */
286
#define STEP(f, a, b, c, d, x, s) \
287
        (a) += f((b), (c), (d)) + (x); \
288
        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
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
295
 * memory accesses is just an optimization.  Nothing will break if it
296
 * doesn't work.
297
 */
298
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
299
#define SET(n) \
300
        (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
301
#define GET(n) \
302
        SET(n)
303
#else
304
#define SET(n) \
305
        (ctx->block[(n)] = \
306
        (MD4_u32plus)ptr[(n) * 4] | \
307
        ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
308
        ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
309
        ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
310
#define GET(n) \
311
        (ctx->block[(n)])
312
#endif
313
314
/*
315
 * This processes one or more 64-byte data blocks, but does NOT update
316
 * the bit counters.  There are no alignment requirements.
317
 */
318
static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
319
{
320
  const unsigned char *ptr;
321
  MD4_u32plus a, b, c, d;
322
323
  ptr = (const unsigned char *)data;
324
325
  a = ctx->a;
326
  b = ctx->b;
327
  c = ctx->c;
328
  d = ctx->d;
329
330
  do {
331
    MD4_u32plus saved_a, saved_b, saved_c, saved_d;
332
333
    saved_a = a;
334
    saved_b = b;
335
    saved_c = c;
336
    saved_d = d;
337
338
/* Round 1 */
339
    STEP(F, a, b, c, d, SET(0), 3)
340
    STEP(F, d, a, b, c, SET(1), 7)
341
    STEP(F, c, d, a, b, SET(2), 11)
342
    STEP(F, b, c, d, a, SET(3), 19)
343
    STEP(F, a, b, c, d, SET(4), 3)
344
    STEP(F, d, a, b, c, SET(5), 7)
345
    STEP(F, c, d, a, b, SET(6), 11)
346
    STEP(F, b, c, d, a, SET(7), 19)
347
    STEP(F, a, b, c, d, SET(8), 3)
348
    STEP(F, d, a, b, c, SET(9), 7)
349
    STEP(F, c, d, a, b, SET(10), 11)
350
    STEP(F, b, c, d, a, SET(11), 19)
351
    STEP(F, a, b, c, d, SET(12), 3)
352
    STEP(F, d, a, b, c, SET(13), 7)
353
    STEP(F, c, d, a, b, SET(14), 11)
354
    STEP(F, b, c, d, a, SET(15), 19)
355
356
/* Round 2 */
357
    STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
358
    STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
359
    STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
360
    STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
361
    STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
362
    STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
363
    STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
364
    STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
365
    STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
366
    STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
367
    STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
368
    STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
369
    STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
370
    STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
371
    STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
372
    STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
373
374
/* Round 3 */
375
    STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
376
    STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
377
    STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
378
    STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
379
    STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
380
    STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
381
    STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
382
    STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
383
    STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
384
    STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
385
    STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
386
    STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
387
    STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
388
    STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
389
    STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
390
    STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
391
392
    a += saved_a;
393
    b += saved_b;
394
    c += saved_c;
395
    d += saved_d;
396
397
    ptr += 64;
398
  } while(size -= 64);
399
400
  ctx->a = a;
401
  ctx->b = b;
402
  ctx->c = c;
403
  ctx->d = d;
404
405
  return ptr;
406
}
407
408
static int MD4_Init(MD4_CTX *ctx)
409
{
410
  ctx->a = 0x67452301;
411
  ctx->b = 0xefcdab89;
412
  ctx->c = 0x98badcfe;
413
  ctx->d = 0x10325476;
414
415
  ctx->lo = 0;
416
  ctx->hi = 0;
417
  return 1;
418
}
419
420
static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
421
{
422
  MD4_u32plus saved_lo;
423
  unsigned long used;
424
425
  saved_lo = ctx->lo;
426
  ctx->lo = (saved_lo + size) & 0x1fffffff;
427
  if(ctx->lo < saved_lo)
428
    ctx->hi++;
429
  ctx->hi += (MD4_u32plus)size >> 29;
430
431
  used = saved_lo & 0x3f;
432
433
  if(used) {
434
    unsigned long available = 64 - used;
435
436
    if(size < available) {
437
      memcpy(&ctx->buffer[used], data, size);
438
      return;
439
    }
440
441
    memcpy(&ctx->buffer[used], data, available);
442
    data = (const unsigned char *)data + available;
443
    size -= available;
444
    body(ctx, ctx->buffer, 64);
445
  }
446
447
  if(size >= 64) {
448
    data = body(ctx, data, size & ~(unsigned long)0x3f);
449
    size &= 0x3f;
450
  }
451
452
  memcpy(ctx->buffer, data, size);
453
}
454
455
static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
456
{
457
  unsigned long used, available;
458
459
  used = ctx->lo & 0x3f;
460
461
  ctx->buffer[used++] = 0x80;
462
463
  available = 64 - used;
464
465
  if(available < 8) {
466
    memset(&ctx->buffer[used], 0, available);
467
    body(ctx, ctx->buffer, 64);
468
    used = 0;
469
    available = 64;
470
  }
471
472
  memset(&ctx->buffer[used], 0, available - 8);
473
474
  ctx->lo <<= 3;
475
  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
476
  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
477
  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
478
  ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
479
  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
480
  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
481
  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
482
  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
483
484
  body(ctx, ctx->buffer, 64);
485
486
  result[0] = curlx_ultouc((ctx->a)&0xff);
487
  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
488
  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
489
  result[3] = curlx_ultouc(ctx->a >> 24);
490
  result[4] = curlx_ultouc((ctx->b)&0xff);
491
  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
492
  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
493
  result[7] = curlx_ultouc(ctx->b >> 24);
494
  result[8] = curlx_ultouc((ctx->c)&0xff);
495
  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
496
  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
497
  result[11] = curlx_ultouc(ctx->c >> 24);
498
  result[12] = curlx_ultouc((ctx->d)&0xff);
499
  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
500
  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
501
  result[15] = curlx_ultouc(ctx->d >> 24);
502
503
  memset(ctx, 0, sizeof(*ctx));
504
}
505
506
#endif /* CRYPTO LIBS */
507
508
CURLcode Curl_md4it(unsigned char *output, const unsigned char *input,
509
                    const size_t len)
510
0
{
511
0
  MD4_CTX ctx;
512
513
#ifdef VOID_MD4_INIT
514
  MD4_Init(&ctx);
515
#else
516
0
  if(!MD4_Init(&ctx))
517
0
    return CURLE_FAILED_INIT;
518
0
#endif
519
520
0
  MD4_Update(&ctx, input, curlx_uztoui(len));
521
0
  MD4_Final(output, &ctx);
522
0
  return CURLE_OK;
523
0
}
524
525
#endif /* USE_CURL_NTLM_CORE */