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