1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #if !defined(CURL_DISABLE_CRYPTO_AUTH)
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
36 #endif /* USE_OPENSSL */
39 #include <mbedtls/config.h>
40 #include <mbedtls/version.h>
42 #if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
43 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
45 #endif /* USE_MBEDTLS */
47 #if defined(USE_GNUTLS_NETTLE)
49 #include <nettle/md4.h>
51 #include "curl_memory.h"
53 /* The last #include file should be: */
56 typedef struct md4_ctx MD4_CTX;
58 static void MD4_Init(MD4_CTX *ctx)
63 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
65 md4_update(ctx, size, data);
68 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
70 md4_digest(ctx, MD4_DIGEST_SIZE, result);
73 #elif defined(USE_GNUTLS)
77 #include "curl_memory.h"
79 /* The last #include file should be: */
82 typedef gcry_md_hd_t MD4_CTX;
84 static void MD4_Init(MD4_CTX *ctx)
86 gcry_md_open(ctx, GCRY_MD_MD4, 0);
89 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
91 gcry_md_write(*ctx, data, size);
94 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
96 memcpy(result, gcry_md_read(*ctx, 0), MD4_DIGEST_LENGTH);
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>
104 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
105 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
106 defined(__MAC_OS_X_VERSION_MIN_ALLOWED) && \
107 (__MAC_OS_X_VERSION_MIN_ALLOWED < 101500)) || \
108 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
109 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
111 #include <CommonCrypto/CommonDigest.h>
113 #include "curl_memory.h"
115 /* The last #include file should be: */
116 #include "memdebug.h"
118 typedef CC_MD4_CTX MD4_CTX;
120 static void MD4_Init(MD4_CTX *ctx)
122 (void)CC_MD4_Init(ctx);
125 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
127 (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
130 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
132 (void)CC_MD4_Final(result, ctx);
135 #elif defined(USE_WIN32_CRYPTO)
137 #include <wincrypt.h>
139 #include "curl_memory.h"
141 /* The last #include file should be: */
142 #include "memdebug.h"
145 HCRYPTPROV hCryptProv;
148 typedef struct md4_ctx MD4_CTX;
150 static void MD4_Init(MD4_CTX *ctx)
155 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
156 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
157 CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
161 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
163 CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
166 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
168 unsigned long length = 0;
170 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
171 if(length == MD4_DIGEST_LENGTH)
172 CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
175 CryptDestroyHash(ctx->hHash);
178 CryptReleaseContext(ctx->hCryptProv, 0);
181 #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
183 #include <mbedtls/md4.h>
185 #include "curl_memory.h"
187 /* The last #include file should be: */
188 #include "memdebug.h"
194 typedef struct md4_ctx MD4_CTX;
196 static void MD4_Init(MD4_CTX *ctx)
202 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
204 if(ctx->data == NULL) {
205 ctx->data = malloc(size);
206 if(ctx->data != NULL) {
207 memcpy(ctx->data, data, size);
213 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
215 if(ctx->data != NULL) {
216 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
217 mbedtls_md4(ctx->data, ctx->size, result);
219 (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
222 Curl_safefree(ctx->data);
228 /* When no other crypto library is available, or the crypto library doesn't
229 * support MD4, we use this code segment this implementation of it
231 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
232 * MD4 Message-Digest Algorithm (RFC 1320).
235 https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
238 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
240 * This software was written by Alexander Peslyak in 2001. No copyright is
241 * claimed, and the software is hereby placed in the public domain. In case
242 * this attempt to disclaim copyright and place the software in the public
243 * domain is deemed null and void, then the software is Copyright (c) 2001
244 * Alexander Peslyak and it is hereby released to the general public under the
247 * Redistribution and use in source and binary forms, with or without
248 * modification, are permitted.
250 * There's ABSOLUTELY NO WARRANTY, express or implied.
252 * (This is a heavily cut-down "BSD license".)
254 * This differs from Colin Plumb's older public domain implementation in that
255 * no exactly 32-bit integer data type is required (any 32-bit or wider
256 * unsigned integer data type will do), there's no compile-time endianness
257 * configuration, and the function prototypes match OpenSSL's. No code from
258 * Colin Plumb's implementation has been reused; this comment merely compares
259 * the properties of the two independent implementations.
261 * The primary goals of this implementation are portability and ease of use.
262 * It is meant to be fast, but not as fast as possible. Some known
263 * optimizations are not included to reduce source code size and avoid
264 * compile-time configuration.
270 /* Any 32-bit or wider unsigned integer data type will do */
271 typedef unsigned int MD4_u32plus;
275 MD4_u32plus a, b, c, d;
276 unsigned char buffer[64];
277 MD4_u32plus block[16];
279 typedef struct md4_ctx MD4_CTX;
281 static void MD4_Init(MD4_CTX *ctx);
282 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
283 static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
286 * The basic MD4 functions.
288 * F and G are optimized compared to their RFC 1320 definitions, with the
289 * optimization for F borrowed from Colin Plumb's MD5 implementation.
291 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
292 #define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
293 #define H(x, y, z) ((x) ^ (y) ^ (z))
296 * The MD4 transformation for all three rounds.
298 #define STEP(f, a, b, c, d, x, s) \
299 (a) += f((b), (c), (d)) + (x); \
300 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
303 * SET reads 4 input bytes in little-endian byte order and stores them
304 * in a properly aligned word in host byte order.
306 * The check for little-endian architectures that tolerate unaligned
307 * memory accesses is just an optimization. Nothing will break if it
310 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
312 (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
318 (MD4_u32plus)ptr[(n) * 4] | \
319 ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
320 ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
321 ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
327 * This processes one or more 64-byte data blocks, but does NOT update
328 * the bit counters. There are no alignment requirements.
330 static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
332 const unsigned char *ptr;
333 MD4_u32plus a, b, c, d;
335 ptr = (const unsigned char *)data;
343 MD4_u32plus saved_a, saved_b, saved_c, saved_d;
351 STEP(F, a, b, c, d, SET(0), 3)
352 STEP(F, d, a, b, c, SET(1), 7)
353 STEP(F, c, d, a, b, SET(2), 11)
354 STEP(F, b, c, d, a, SET(3), 19)
355 STEP(F, a, b, c, d, SET(4), 3)
356 STEP(F, d, a, b, c, SET(5), 7)
357 STEP(F, c, d, a, b, SET(6), 11)
358 STEP(F, b, c, d, a, SET(7), 19)
359 STEP(F, a, b, c, d, SET(8), 3)
360 STEP(F, d, a, b, c, SET(9), 7)
361 STEP(F, c, d, a, b, SET(10), 11)
362 STEP(F, b, c, d, a, SET(11), 19)
363 STEP(F, a, b, c, d, SET(12), 3)
364 STEP(F, d, a, b, c, SET(13), 7)
365 STEP(F, c, d, a, b, SET(14), 11)
366 STEP(F, b, c, d, a, SET(15), 19)
369 STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
370 STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
371 STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
372 STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
373 STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
374 STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
375 STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
376 STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
377 STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
378 STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
379 STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
380 STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
381 STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
382 STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
383 STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
384 STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
387 STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
388 STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
389 STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
390 STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
391 STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
392 STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
393 STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
394 STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
395 STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
396 STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
397 STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
398 STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
399 STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
400 STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
401 STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
402 STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
420 static void MD4_Init(MD4_CTX *ctx)
431 static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
433 MD4_u32plus saved_lo;
437 ctx->lo = (saved_lo + size) & 0x1fffffff;
438 if(ctx->lo < saved_lo)
440 ctx->hi += (MD4_u32plus)size >> 29;
442 used = saved_lo & 0x3f;
445 unsigned long available = 64 - used;
447 if(size < available) {
448 memcpy(&ctx->buffer[used], data, size);
452 memcpy(&ctx->buffer[used], data, available);
453 data = (const unsigned char *)data + available;
455 body(ctx, ctx->buffer, 64);
459 data = body(ctx, data, size & ~(unsigned long)0x3f);
463 memcpy(ctx->buffer, data, size);
466 static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
468 unsigned long used, available;
470 used = ctx->lo & 0x3f;
472 ctx->buffer[used++] = 0x80;
474 available = 64 - used;
477 memset(&ctx->buffer[used], 0, available);
478 body(ctx, ctx->buffer, 64);
483 memset(&ctx->buffer[used], 0, available - 8);
486 ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
487 ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
488 ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
489 ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
490 ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
491 ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
492 ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
493 ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
495 body(ctx, ctx->buffer, 64);
497 result[0] = curlx_ultouc((ctx->a)&0xff);
498 result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
499 result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
500 result[3] = curlx_ultouc(ctx->a >> 24);
501 result[4] = curlx_ultouc((ctx->b)&0xff);
502 result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
503 result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
504 result[7] = curlx_ultouc(ctx->b >> 24);
505 result[8] = curlx_ultouc((ctx->c)&0xff);
506 result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
507 result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
508 result[11] = curlx_ultouc(ctx->c >> 24);
509 result[12] = curlx_ultouc((ctx->d)&0xff);
510 result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
511 result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
512 result[15] = curlx_ultouc(ctx->d >> 24);
514 memset(ctx, 0, sizeof(*ctx));
517 #endif /* CRYPTO LIBS */
519 void Curl_md4it(unsigned char *output, const unsigned char *input,
525 MD4_Update(&ctx, input, curlx_uztoui(len));
526 MD4_Final(output, &ctx);
529 #endif /* CURL_DISABLE_CRYPTO_AUTH */