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