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