md5.c (20287B)
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) && !defined(USE_WINDOWS_SSPI)) \ 28 || !defined(CURL_DISABLE_DIGEST_AUTH) 29 30 #include <string.h> 31 #include <curl/curl.h> 32 33 #include "curl_md5.h" 34 #include "curl_hmac.h" 35 #include "curlx/warnless.h" 36 37 #ifdef USE_MBEDTLS 38 #include <mbedtls/version.h> 39 40 #if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \ 41 (MBEDTLS_VERSION_NUMBER < 0x03000000) 42 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS 43 #endif 44 #endif /* USE_MBEDTLS */ 45 46 #ifdef USE_OPENSSL 47 #include <openssl/opensslconf.h> 48 #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0) 49 #define USE_OPENSSL_MD5 50 #endif 51 #endif 52 53 #ifdef USE_WOLFSSL 54 #include <wolfssl/options.h> 55 #ifndef NO_MD5 56 #define USE_WOLFSSL_MD5 57 #endif 58 #endif 59 60 #if defined(USE_GNUTLS) 61 #include <nettle/md5.h> 62 #elif defined(USE_OPENSSL_MD5) 63 #include <openssl/md5.h> 64 #elif defined(USE_WOLFSSL_MD5) 65 #include <wolfssl/openssl/md5.h> 66 #elif defined(USE_MBEDTLS) 67 #include <mbedtls/md5.h> 68 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ 69 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \ 70 defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ 71 (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \ 72 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ 73 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \ 74 defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ 75 (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000)) 76 #define AN_APPLE_OS 77 #include <CommonCrypto/CommonDigest.h> 78 #elif defined(USE_WIN32_CRYPTO) 79 #include <wincrypt.h> 80 #endif 81 82 /* The last 3 #include files should be in this order */ 83 #include "curl_printf.h" 84 #include "curl_memory.h" 85 #include "memdebug.h" 86 87 #if defined(USE_GNUTLS) 88 89 typedef struct md5_ctx my_md5_ctx; 90 91 static CURLcode my_md5_init(void *ctx) 92 { 93 md5_init(ctx); 94 return CURLE_OK; 95 } 96 97 static void my_md5_update(void *ctx, 98 const unsigned char *input, 99 unsigned int inputLen) 100 { 101 md5_update(ctx, inputLen, input); 102 } 103 104 static void my_md5_final(unsigned char *digest, void *ctx) 105 { 106 md5_digest(ctx, 16, digest); 107 } 108 109 #elif defined(USE_OPENSSL_MD5) || \ 110 (defined(USE_WOLFSSL_MD5) && !defined(OPENSSL_COEXIST)) 111 112 typedef MD5_CTX my_md5_ctx; 113 114 static CURLcode my_md5_init(void *ctx) 115 { 116 if(!MD5_Init(ctx)) 117 return CURLE_OUT_OF_MEMORY; 118 119 return CURLE_OK; 120 } 121 122 static void my_md5_update(void *ctx, 123 const unsigned char *input, 124 unsigned int len) 125 { 126 (void)MD5_Update(ctx, input, len); 127 } 128 129 static void my_md5_final(unsigned char *digest, void *ctx) 130 { 131 (void)MD5_Final(digest, ctx); 132 } 133 134 #elif defined(USE_WOLFSSL_MD5) 135 136 typedef WOLFSSL_MD5_CTX my_md5_ctx; 137 138 static CURLcode my_md5_init(void *ctx) 139 { 140 if(!wolfSSL_MD5_Init(ctx)) 141 return CURLE_OUT_OF_MEMORY; 142 143 return CURLE_OK; 144 } 145 146 static void my_md5_update(void *ctx, 147 const unsigned char *input, 148 unsigned int len) 149 { 150 (void)wolfSSL_MD5_Update(ctx, input, len); 151 } 152 153 static void my_md5_final(unsigned char *digest, void *ctx) 154 { 155 (void)wolfSSL_MD5_Final(digest, ctx); 156 } 157 158 #elif defined(USE_MBEDTLS) 159 160 typedef mbedtls_md5_context my_md5_ctx; 161 162 static CURLcode my_md5_init(void *ctx) 163 { 164 #if (MBEDTLS_VERSION_NUMBER >= 0x03000000) 165 if(mbedtls_md5_starts(ctx)) 166 return CURLE_OUT_OF_MEMORY; 167 #elif defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 168 if(mbedtls_md5_starts_ret(ctx)) 169 return CURLE_OUT_OF_MEMORY; 170 #else 171 (void)mbedtls_md5_starts(ctx); 172 #endif 173 return CURLE_OK; 174 } 175 176 static void my_md5_update(void *ctx, 177 const unsigned char *data, 178 unsigned int length) 179 { 180 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 181 (void) mbedtls_md5_update(ctx, data, length); 182 #else 183 (void) mbedtls_md5_update_ret(ctx, data, length); 184 #endif 185 } 186 187 static void my_md5_final(unsigned char *digest, void *ctx) 188 { 189 #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 190 (void) mbedtls_md5_finish(ctx, digest); 191 #else 192 (void) mbedtls_md5_finish_ret(ctx, digest); 193 #endif 194 } 195 196 #elif defined(AN_APPLE_OS) 197 198 /* For Apple operating systems: CommonCrypto has the functions we need. 199 These functions are available on Tiger and later, as well as iOS 2.0 200 and later. If you are building for an older cat, well, sorry. 201 202 Declaring the functions as static like this seems to be a bit more 203 reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */ 204 # define my_md5_ctx CC_MD5_CTX 205 206 static CURLcode my_md5_init(void *ctx) 207 { 208 if(!CC_MD5_Init(ctx)) 209 return CURLE_OUT_OF_MEMORY; 210 211 return CURLE_OK; 212 } 213 214 static void my_md5_update(void *ctx, 215 const unsigned char *input, 216 unsigned int inputLen) 217 { 218 CC_MD5_Update(ctx, input, inputLen); 219 } 220 221 static void my_md5_final(unsigned char *digest, void *ctx) 222 { 223 CC_MD5_Final(digest, ctx); 224 } 225 226 #elif defined(USE_WIN32_CRYPTO) 227 228 struct md5_ctx { 229 HCRYPTPROV hCryptProv; 230 HCRYPTHASH hHash; 231 }; 232 typedef struct md5_ctx my_md5_ctx; 233 234 static CURLcode my_md5_init(void *in) 235 { 236 my_md5_ctx *ctx = (my_md5_ctx *)in; 237 if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL, 238 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 239 return CURLE_OUT_OF_MEMORY; 240 241 if(!CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash)) { 242 CryptReleaseContext(ctx->hCryptProv, 0); 243 ctx->hCryptProv = 0; 244 return CURLE_FAILED_INIT; 245 } 246 247 return CURLE_OK; 248 } 249 250 static void my_md5_update(void *in, 251 const unsigned char *input, 252 unsigned int inputLen) 253 { 254 my_md5_ctx *ctx = in; 255 #ifdef __MINGW32CE__ 256 CryptHashData(ctx->hHash, (BYTE *)CURL_UNCONST(input), inputLen, 0); 257 #else 258 CryptHashData(ctx->hHash, (const BYTE *)input, inputLen, 0); 259 #endif 260 } 261 262 static void my_md5_final(unsigned char *digest, void *in) 263 { 264 my_md5_ctx *ctx = (my_md5_ctx *)in; 265 unsigned long length = 0; 266 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); 267 if(length == 16) 268 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); 269 if(ctx->hHash) 270 CryptDestroyHash(ctx->hHash); 271 if(ctx->hCryptProv) 272 CryptReleaseContext(ctx->hCryptProv, 0); 273 } 274 275 #else 276 277 /* When no other crypto library is available we use this code segment */ 278 279 /* 280 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 281 * MD5 Message-Digest Algorithm (RFC 1321). 282 * 283 * Homepage: 284 https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 285 * 286 * Author: 287 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 288 * 289 * This software was written by Alexander Peslyak in 2001. No copyright is 290 * claimed, and the software is hereby placed in the public domain. 291 * In case this attempt to disclaim copyright and place the software in the 292 * public domain is deemed null and void, then the software is 293 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 294 * general public under the following terms: 295 * 296 * Redistribution and use in source and binary forms, with or without 297 * modification, are permitted. 298 * 299 * There is ABSOLUTELY NO WARRANTY, express or implied. 300 * 301 * (This is a heavily cut-down "BSD license".) 302 * 303 * This differs from Colin Plumb's older public domain implementation in that 304 * no exactly 32-bit integer data type is required (any 32-bit or wider 305 * unsigned integer data type will do), there is no compile-time endianness 306 * configuration, and the function prototypes match OpenSSL's. No code from 307 * Colin Plumb's implementation has been reused; this comment merely compares 308 * the properties of the two independent implementations. 309 * 310 * The primary goals of this implementation are portability and ease of use. 311 * It is meant to be fast, but not as fast as possible. Some known 312 * optimizations are not included to reduce source code size and avoid 313 * compile-time configuration. 314 */ 315 316 /* Any 32-bit or wider unsigned integer data type will do */ 317 typedef unsigned int MD5_u32plus; 318 319 struct md5_ctx { 320 MD5_u32plus lo, hi; 321 MD5_u32plus a, b, c, d; 322 unsigned char buffer[64]; 323 MD5_u32plus block[16]; 324 }; 325 typedef struct md5_ctx my_md5_ctx; 326 327 static CURLcode my_md5_init(void *ctx); 328 static void my_md5_update(void *ctx, const unsigned char *data, 329 unsigned int size); 330 static void my_md5_final(unsigned char *result, void *ctx); 331 332 /* 333 * The basic MD5 functions. 334 * 335 * F and G are optimized compared to their RFC 1321 definitions for 336 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 337 * implementation. 338 */ 339 #define MD5_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 340 #define MD5_G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 341 #define MD5_H(x, y, z) (((x) ^ (y)) ^ (z)) 342 #define MD5_H2(x, y, z) ((x) ^ ((y) ^ (z))) 343 #define MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) 344 345 /* 346 * The MD5 transformation for all four rounds. 347 */ 348 #define MD5_STEP(f, a, b, c, d, x, t, s) \ 349 (a) += f((b), (c), (d)) + (x) + (t); \ 350 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 351 (a) += (b); 352 353 /* 354 * SET reads 4 input bytes in little-endian byte order and stores them 355 * in a properly aligned word in host byte order. 356 * 357 * The check for little-endian architectures that tolerate unaligned 358 * memory accesses is just an optimization. Nothing will break if it 359 * does not work. 360 */ 361 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 362 #define MD5_SET(n) \ 363 (*(const MD5_u32plus *)(const void *)&ptr[(n) * 4]) 364 #define MD5_GET(n) \ 365 MD5_SET(n) 366 #else 367 #define MD5_SET(n) \ 368 (ctx->block[(n)] = \ 369 (MD5_u32plus)ptr[(n) * 4] | \ 370 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 371 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 372 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 373 #define MD5_GET(n) \ 374 (ctx->block[(n)]) 375 #endif 376 377 /* 378 * This processes one or more 64-byte data blocks, but does NOT update 379 * the bit counters. There are no alignment requirements. 380 */ 381 static const void *my_md5_body(my_md5_ctx *ctx, 382 const void *data, unsigned long size) 383 { 384 const unsigned char *ptr; 385 MD5_u32plus a, b, c, d; 386 387 ptr = (const unsigned char *)data; 388 389 a = ctx->a; 390 b = ctx->b; 391 c = ctx->c; 392 d = ctx->d; 393 394 do { 395 MD5_u32plus saved_a, saved_b, saved_c, saved_d; 396 397 saved_a = a; 398 saved_b = b; 399 saved_c = c; 400 saved_d = d; 401 402 /* Round 1 */ 403 MD5_STEP(MD5_F, a, b, c, d, MD5_SET(0), 0xd76aa478, 7) 404 MD5_STEP(MD5_F, d, a, b, c, MD5_SET(1), 0xe8c7b756, 12) 405 MD5_STEP(MD5_F, c, d, a, b, MD5_SET(2), 0x242070db, 17) 406 MD5_STEP(MD5_F, b, c, d, a, MD5_SET(3), 0xc1bdceee, 22) 407 MD5_STEP(MD5_F, a, b, c, d, MD5_SET(4), 0xf57c0faf, 7) 408 MD5_STEP(MD5_F, d, a, b, c, MD5_SET(5), 0x4787c62a, 12) 409 MD5_STEP(MD5_F, c, d, a, b, MD5_SET(6), 0xa8304613, 17) 410 MD5_STEP(MD5_F, b, c, d, a, MD5_SET(7), 0xfd469501, 22) 411 MD5_STEP(MD5_F, a, b, c, d, MD5_SET(8), 0x698098d8, 7) 412 MD5_STEP(MD5_F, d, a, b, c, MD5_SET(9), 0x8b44f7af, 12) 413 MD5_STEP(MD5_F, c, d, a, b, MD5_SET(10), 0xffff5bb1, 17) 414 MD5_STEP(MD5_F, b, c, d, a, MD5_SET(11), 0x895cd7be, 22) 415 MD5_STEP(MD5_F, a, b, c, d, MD5_SET(12), 0x6b901122, 7) 416 MD5_STEP(MD5_F, d, a, b, c, MD5_SET(13), 0xfd987193, 12) 417 MD5_STEP(MD5_F, c, d, a, b, MD5_SET(14), 0xa679438e, 17) 418 MD5_STEP(MD5_F, b, c, d, a, MD5_SET(15), 0x49b40821, 22) 419 420 /* Round 2 */ 421 MD5_STEP(MD5_G, a, b, c, d, MD5_GET(1), 0xf61e2562, 5) 422 MD5_STEP(MD5_G, d, a, b, c, MD5_GET(6), 0xc040b340, 9) 423 MD5_STEP(MD5_G, c, d, a, b, MD5_GET(11), 0x265e5a51, 14) 424 MD5_STEP(MD5_G, b, c, d, a, MD5_GET(0), 0xe9b6c7aa, 20) 425 MD5_STEP(MD5_G, a, b, c, d, MD5_GET(5), 0xd62f105d, 5) 426 MD5_STEP(MD5_G, d, a, b, c, MD5_GET(10), 0x02441453, 9) 427 MD5_STEP(MD5_G, c, d, a, b, MD5_GET(15), 0xd8a1e681, 14) 428 MD5_STEP(MD5_G, b, c, d, a, MD5_GET(4), 0xe7d3fbc8, 20) 429 MD5_STEP(MD5_G, a, b, c, d, MD5_GET(9), 0x21e1cde6, 5) 430 MD5_STEP(MD5_G, d, a, b, c, MD5_GET(14), 0xc33707d6, 9) 431 MD5_STEP(MD5_G, c, d, a, b, MD5_GET(3), 0xf4d50d87, 14) 432 MD5_STEP(MD5_G, b, c, d, a, MD5_GET(8), 0x455a14ed, 20) 433 MD5_STEP(MD5_G, a, b, c, d, MD5_GET(13), 0xa9e3e905, 5) 434 MD5_STEP(MD5_G, d, a, b, c, MD5_GET(2), 0xfcefa3f8, 9) 435 MD5_STEP(MD5_G, c, d, a, b, MD5_GET(7), 0x676f02d9, 14) 436 MD5_STEP(MD5_G, b, c, d, a, MD5_GET(12), 0x8d2a4c8a, 20) 437 438 /* Round 3 */ 439 MD5_STEP(MD5_H, a, b, c, d, MD5_GET(5), 0xfffa3942, 4) 440 MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(8), 0x8771f681, 11) 441 MD5_STEP(MD5_H, c, d, a, b, MD5_GET(11), 0x6d9d6122, 16) 442 MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(14), 0xfde5380c, 23) 443 MD5_STEP(MD5_H, a, b, c, d, MD5_GET(1), 0xa4beea44, 4) 444 MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(4), 0x4bdecfa9, 11) 445 MD5_STEP(MD5_H, c, d, a, b, MD5_GET(7), 0xf6bb4b60, 16) 446 MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(10), 0xbebfbc70, 23) 447 MD5_STEP(MD5_H, a, b, c, d, MD5_GET(13), 0x289b7ec6, 4) 448 MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(0), 0xeaa127fa, 11) 449 MD5_STEP(MD5_H, c, d, a, b, MD5_GET(3), 0xd4ef3085, 16) 450 MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(6), 0x04881d05, 23) 451 MD5_STEP(MD5_H, a, b, c, d, MD5_GET(9), 0xd9d4d039, 4) 452 MD5_STEP(MD5_H2, d, a, b, c, MD5_GET(12), 0xe6db99e5, 11) 453 MD5_STEP(MD5_H, c, d, a, b, MD5_GET(15), 0x1fa27cf8, 16) 454 MD5_STEP(MD5_H2, b, c, d, a, MD5_GET(2), 0xc4ac5665, 23) 455 456 /* Round 4 */ 457 MD5_STEP(MD5_I, a, b, c, d, MD5_GET(0), 0xf4292244, 6) 458 MD5_STEP(MD5_I, d, a, b, c, MD5_GET(7), 0x432aff97, 10) 459 MD5_STEP(MD5_I, c, d, a, b, MD5_GET(14), 0xab9423a7, 15) 460 MD5_STEP(MD5_I, b, c, d, a, MD5_GET(5), 0xfc93a039, 21) 461 MD5_STEP(MD5_I, a, b, c, d, MD5_GET(12), 0x655b59c3, 6) 462 MD5_STEP(MD5_I, d, a, b, c, MD5_GET(3), 0x8f0ccc92, 10) 463 MD5_STEP(MD5_I, c, d, a, b, MD5_GET(10), 0xffeff47d, 15) 464 MD5_STEP(MD5_I, b, c, d, a, MD5_GET(1), 0x85845dd1, 21) 465 MD5_STEP(MD5_I, a, b, c, d, MD5_GET(8), 0x6fa87e4f, 6) 466 MD5_STEP(MD5_I, d, a, b, c, MD5_GET(15), 0xfe2ce6e0, 10) 467 MD5_STEP(MD5_I, c, d, a, b, MD5_GET(6), 0xa3014314, 15) 468 MD5_STEP(MD5_I, b, c, d, a, MD5_GET(13), 0x4e0811a1, 21) 469 MD5_STEP(MD5_I, a, b, c, d, MD5_GET(4), 0xf7537e82, 6) 470 MD5_STEP(MD5_I, d, a, b, c, MD5_GET(11), 0xbd3af235, 10) 471 MD5_STEP(MD5_I, c, d, a, b, MD5_GET(2), 0x2ad7d2bb, 15) 472 MD5_STEP(MD5_I, b, c, d, a, MD5_GET(9), 0xeb86d391, 21) 473 474 a += saved_a; 475 b += saved_b; 476 c += saved_c; 477 d += saved_d; 478 479 ptr += 64; 480 } while(size -= 64); 481 482 ctx->a = a; 483 ctx->b = b; 484 ctx->c = c; 485 ctx->d = d; 486 487 return ptr; 488 } 489 490 static CURLcode my_md5_init(void *in) 491 { 492 my_md5_ctx *ctx = (my_md5_ctx *)in; 493 ctx->a = 0x67452301; 494 ctx->b = 0xefcdab89; 495 ctx->c = 0x98badcfe; 496 ctx->d = 0x10325476; 497 498 ctx->lo = 0; 499 ctx->hi = 0; 500 501 return CURLE_OK; 502 } 503 504 static void my_md5_update(void *in, const unsigned char *data, 505 unsigned int size) 506 { 507 MD5_u32plus saved_lo; 508 unsigned int used; 509 my_md5_ctx *ctx = (my_md5_ctx *)in; 510 511 saved_lo = ctx->lo; 512 ctx->lo = (saved_lo + size) & 0x1fffffff; 513 if(ctx->lo < saved_lo) 514 ctx->hi++; 515 ctx->hi += (MD5_u32plus)size >> 29; 516 517 used = saved_lo & 0x3f; 518 519 if(used) { 520 unsigned int available = 64 - used; 521 522 if(size < available) { 523 memcpy(&ctx->buffer[used], data, size); 524 return; 525 } 526 527 memcpy(&ctx->buffer[used], data, available); 528 data = (const unsigned char *)data + available; 529 size -= available; 530 my_md5_body(ctx, ctx->buffer, 64); 531 } 532 533 if(size >= 64) { 534 data = my_md5_body(ctx, data, size & ~(unsigned long)0x3f); 535 size &= 0x3f; 536 } 537 538 memcpy(ctx->buffer, data, size); 539 } 540 541 static void my_md5_final(unsigned char *result, void *in) 542 { 543 unsigned int used, available; 544 my_md5_ctx *ctx = (my_md5_ctx *)in; 545 546 used = ctx->lo & 0x3f; 547 548 ctx->buffer[used++] = 0x80; 549 550 available = 64 - used; 551 552 if(available < 8) { 553 memset(&ctx->buffer[used], 0, available); 554 my_md5_body(ctx, ctx->buffer, 64); 555 used = 0; 556 available = 64; 557 } 558 559 memset(&ctx->buffer[used], 0, available - 8); 560 561 ctx->lo <<= 3; 562 ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff); 563 ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff); 564 ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff); 565 ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24); 566 ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff); 567 ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff); 568 ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff); 569 ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); 570 571 my_md5_body(ctx, ctx->buffer, 64); 572 573 result[0] = curlx_ultouc((ctx->a)&0xff); 574 result[1] = curlx_ultouc((ctx->a >> 8)&0xff); 575 result[2] = curlx_ultouc((ctx->a >> 16)&0xff); 576 result[3] = curlx_ultouc(ctx->a >> 24); 577 result[4] = curlx_ultouc((ctx->b)&0xff); 578 result[5] = curlx_ultouc((ctx->b >> 8)&0xff); 579 result[6] = curlx_ultouc((ctx->b >> 16)&0xff); 580 result[7] = curlx_ultouc(ctx->b >> 24); 581 result[8] = curlx_ultouc((ctx->c)&0xff); 582 result[9] = curlx_ultouc((ctx->c >> 8)&0xff); 583 result[10] = curlx_ultouc((ctx->c >> 16)&0xff); 584 result[11] = curlx_ultouc(ctx->c >> 24); 585 result[12] = curlx_ultouc((ctx->d)&0xff); 586 result[13] = curlx_ultouc((ctx->d >> 8)&0xff); 587 result[14] = curlx_ultouc((ctx->d >> 16)&0xff); 588 result[15] = curlx_ultouc(ctx->d >> 24); 589 590 memset(ctx, 0, sizeof(*ctx)); 591 } 592 593 #endif /* CRYPTO LIBS */ 594 595 const struct HMAC_params Curl_HMAC_MD5 = { 596 my_md5_init, /* Hash initialization function. */ 597 my_md5_update, /* Hash update function. */ 598 my_md5_final, /* Hash computation end function. */ 599 sizeof(my_md5_ctx), /* Size of hash context structure. */ 600 64, /* Maximum key length. */ 601 16 /* Result size. */ 602 }; 603 604 const struct MD5_params Curl_DIGEST_MD5 = { 605 my_md5_init, /* Digest initialization function */ 606 my_md5_update, /* Digest update function */ 607 my_md5_final, /* Digest computation end function */ 608 sizeof(my_md5_ctx), /* Size of digest context struct */ 609 16 /* Result size */ 610 }; 611 612 /* 613 * @unittest: 1601 614 * Returns CURLE_OK on success. 615 */ 616 CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input, 617 const size_t len) 618 { 619 CURLcode result; 620 my_md5_ctx ctx; 621 622 result = my_md5_init(&ctx); 623 if(!result) { 624 my_md5_update(&ctx, input, curlx_uztoui(len)); 625 my_md5_final(outbuffer, &ctx); 626 } 627 return result; 628 } 629 630 struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params) 631 { 632 struct MD5_context *ctxt; 633 634 /* Create MD5 context */ 635 ctxt = malloc(sizeof(*ctxt)); 636 637 if(!ctxt) 638 return ctxt; 639 640 ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize); 641 642 if(!ctxt->md5_hashctx) { 643 free(ctxt); 644 return NULL; 645 } 646 647 ctxt->md5_hash = md5params; 648 649 if((*md5params->md5_init_func)(ctxt->md5_hashctx)) { 650 free(ctxt->md5_hashctx); 651 free(ctxt); 652 return NULL; 653 } 654 655 return ctxt; 656 } 657 658 CURLcode Curl_MD5_update(struct MD5_context *context, 659 const unsigned char *data, 660 unsigned int len) 661 { 662 (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len); 663 664 return CURLE_OK; 665 } 666 667 CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result) 668 { 669 (*context->md5_hash->md5_final_func)(result, context->md5_hashctx); 670 671 free(context->md5_hashctx); 672 free(context); 673 674 return CURLE_OK; 675 } 676 677 #endif /* Using NTLM (without SSPI) || Digest */