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