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