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