xref: /curl/lib/md4.c (revision 1f877b0f)
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