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