113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#if (defined(USE_CURL_NTLM_CORE) && !defined(USE_WINDOWS_SSPI)) \ 2813498266Sopenharmony_ci || !defined(CURL_DISABLE_DIGEST_AUTH) 2913498266Sopenharmony_ci 3013498266Sopenharmony_ci#include <string.h> 3113498266Sopenharmony_ci#include <curl/curl.h> 3213498266Sopenharmony_ci 3313498266Sopenharmony_ci#include "curl_md5.h" 3413498266Sopenharmony_ci#include "curl_hmac.h" 3513498266Sopenharmony_ci#include "warnless.h" 3613498266Sopenharmony_ci 3713498266Sopenharmony_ci#ifdef USE_MBEDTLS 3813498266Sopenharmony_ci#include <mbedtls/version.h> 3913498266Sopenharmony_ci 4013498266Sopenharmony_ci#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \ 4113498266Sopenharmony_ci (MBEDTLS_VERSION_NUMBER < 0x03000000) 4213498266Sopenharmony_ci #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS 4313498266Sopenharmony_ci#endif 4413498266Sopenharmony_ci#endif /* USE_MBEDTLS */ 4513498266Sopenharmony_ci 4613498266Sopenharmony_ci#ifdef USE_OPENSSL 4713498266Sopenharmony_ci #include <openssl/opensslconf.h> 4813498266Sopenharmony_ci #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0) 4913498266Sopenharmony_ci #define USE_OPENSSL_MD5 5013498266Sopenharmony_ci #endif 5113498266Sopenharmony_ci#endif 5213498266Sopenharmony_ci 5313498266Sopenharmony_ci#ifdef USE_WOLFSSL 5413498266Sopenharmony_ci #include <wolfssl/options.h> 5513498266Sopenharmony_ci #ifndef NO_MD5 5613498266Sopenharmony_ci #define USE_WOLFSSL_MD5 5713498266Sopenharmony_ci #endif 5813498266Sopenharmony_ci#endif 5913498266Sopenharmony_ci 6013498266Sopenharmony_ci#if defined(USE_GNUTLS) 6113498266Sopenharmony_ci#include <nettle/md5.h> 6213498266Sopenharmony_ci#elif defined(USE_OPENSSL_MD5) 6313498266Sopenharmony_ci#include <openssl/md5.h> 6413498266Sopenharmony_ci#elif defined(USE_WOLFSSL_MD5) 6513498266Sopenharmony_ci#include <wolfssl/openssl/md5.h> 6613498266Sopenharmony_ci#elif defined(USE_MBEDTLS) 6713498266Sopenharmony_ci#include <mbedtls/md5.h> 6813498266Sopenharmony_ci#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ 6913498266Sopenharmony_ci (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \ 7013498266Sopenharmony_ci defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ 7113498266Sopenharmony_ci (__MAC_OS_X_VERSION_MIN_REQUIRED < 101500)) || \ 7213498266Sopenharmony_ci (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ 7313498266Sopenharmony_ci (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000) && \ 7413498266Sopenharmony_ci defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \ 7513498266Sopenharmony_ci (__IPHONE_OS_VERSION_MIN_REQUIRED < 130000)) 7613498266Sopenharmony_ci#define AN_APPLE_OS 7713498266Sopenharmony_ci#include <CommonCrypto/CommonDigest.h> 7813498266Sopenharmony_ci#elif defined(USE_WIN32_CRYPTO) 7913498266Sopenharmony_ci#include <wincrypt.h> 8013498266Sopenharmony_ci#endif 8113498266Sopenharmony_ci 8213498266Sopenharmony_ci/* The last 3 #include files should be in this order */ 8313498266Sopenharmony_ci#include "curl_printf.h" 8413498266Sopenharmony_ci#include "curl_memory.h" 8513498266Sopenharmony_ci#include "memdebug.h" 8613498266Sopenharmony_ci 8713498266Sopenharmony_ci#if defined(USE_GNUTLS) 8813498266Sopenharmony_ci 8913498266Sopenharmony_citypedef struct md5_ctx my_md5_ctx; 9013498266Sopenharmony_ci 9113498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx) 9213498266Sopenharmony_ci{ 9313498266Sopenharmony_ci md5_init(ctx); 9413498266Sopenharmony_ci return CURLE_OK; 9513498266Sopenharmony_ci} 9613498266Sopenharmony_ci 9713498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, 9813498266Sopenharmony_ci const unsigned char *input, 9913498266Sopenharmony_ci unsigned int inputLen) 10013498266Sopenharmony_ci{ 10113498266Sopenharmony_ci md5_update(ctx, inputLen, input); 10213498266Sopenharmony_ci} 10313498266Sopenharmony_ci 10413498266Sopenharmony_cistatic void my_md5_final(unsigned char *digest, my_md5_ctx *ctx) 10513498266Sopenharmony_ci{ 10613498266Sopenharmony_ci md5_digest(ctx, 16, digest); 10713498266Sopenharmony_ci} 10813498266Sopenharmony_ci 10913498266Sopenharmony_ci#elif defined(USE_OPENSSL_MD5) || defined(USE_WOLFSSL_MD5) 11013498266Sopenharmony_ci 11113498266Sopenharmony_citypedef MD5_CTX my_md5_ctx; 11213498266Sopenharmony_ci 11313498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx) 11413498266Sopenharmony_ci{ 11513498266Sopenharmony_ci if(!MD5_Init(ctx)) 11613498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 11713498266Sopenharmony_ci 11813498266Sopenharmony_ci return CURLE_OK; 11913498266Sopenharmony_ci} 12013498266Sopenharmony_ci 12113498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, 12213498266Sopenharmony_ci const unsigned char *input, 12313498266Sopenharmony_ci unsigned int len) 12413498266Sopenharmony_ci{ 12513498266Sopenharmony_ci (void)MD5_Update(ctx, input, len); 12613498266Sopenharmony_ci} 12713498266Sopenharmony_ci 12813498266Sopenharmony_cistatic void my_md5_final(unsigned char *digest, my_md5_ctx *ctx) 12913498266Sopenharmony_ci{ 13013498266Sopenharmony_ci (void)MD5_Final(digest, ctx); 13113498266Sopenharmony_ci} 13213498266Sopenharmony_ci 13313498266Sopenharmony_ci#elif defined(USE_MBEDTLS) 13413498266Sopenharmony_ci 13513498266Sopenharmony_citypedef mbedtls_md5_context my_md5_ctx; 13613498266Sopenharmony_ci 13713498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx) 13813498266Sopenharmony_ci{ 13913498266Sopenharmony_ci#if (MBEDTLS_VERSION_NUMBER >= 0x03000000) 14013498266Sopenharmony_ci if(mbedtls_md5_starts(ctx)) 14113498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 14213498266Sopenharmony_ci#elif defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 14313498266Sopenharmony_ci if(mbedtls_md5_starts_ret(ctx)) 14413498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 14513498266Sopenharmony_ci#else 14613498266Sopenharmony_ci (void)mbedtls_md5_starts(ctx); 14713498266Sopenharmony_ci#endif 14813498266Sopenharmony_ci return CURLE_OK; 14913498266Sopenharmony_ci} 15013498266Sopenharmony_ci 15113498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, 15213498266Sopenharmony_ci const unsigned char *data, 15313498266Sopenharmony_ci unsigned int length) 15413498266Sopenharmony_ci{ 15513498266Sopenharmony_ci#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 15613498266Sopenharmony_ci (void) mbedtls_md5_update(ctx, data, length); 15713498266Sopenharmony_ci#else 15813498266Sopenharmony_ci (void) mbedtls_md5_update_ret(ctx, data, length); 15913498266Sopenharmony_ci#endif 16013498266Sopenharmony_ci} 16113498266Sopenharmony_ci 16213498266Sopenharmony_cistatic void my_md5_final(unsigned char *digest, my_md5_ctx *ctx) 16313498266Sopenharmony_ci{ 16413498266Sopenharmony_ci#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS) 16513498266Sopenharmony_ci (void) mbedtls_md5_finish(ctx, digest); 16613498266Sopenharmony_ci#else 16713498266Sopenharmony_ci (void) mbedtls_md5_finish_ret(ctx, digest); 16813498266Sopenharmony_ci#endif 16913498266Sopenharmony_ci} 17013498266Sopenharmony_ci 17113498266Sopenharmony_ci#elif defined(AN_APPLE_OS) 17213498266Sopenharmony_ci 17313498266Sopenharmony_ci/* For Apple operating systems: CommonCrypto has the functions we need. 17413498266Sopenharmony_ci These functions are available on Tiger and later, as well as iOS 2.0 17513498266Sopenharmony_ci and later. If you're building for an older cat, well, sorry. 17613498266Sopenharmony_ci 17713498266Sopenharmony_ci Declaring the functions as static like this seems to be a bit more 17813498266Sopenharmony_ci reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */ 17913498266Sopenharmony_ci# define my_md5_ctx CC_MD5_CTX 18013498266Sopenharmony_ci 18113498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx) 18213498266Sopenharmony_ci{ 18313498266Sopenharmony_ci if(!CC_MD5_Init(ctx)) 18413498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 18513498266Sopenharmony_ci 18613498266Sopenharmony_ci return CURLE_OK; 18713498266Sopenharmony_ci} 18813498266Sopenharmony_ci 18913498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, 19013498266Sopenharmony_ci const unsigned char *input, 19113498266Sopenharmony_ci unsigned int inputLen) 19213498266Sopenharmony_ci{ 19313498266Sopenharmony_ci CC_MD5_Update(ctx, input, inputLen); 19413498266Sopenharmony_ci} 19513498266Sopenharmony_ci 19613498266Sopenharmony_cistatic void my_md5_final(unsigned char *digest, my_md5_ctx *ctx) 19713498266Sopenharmony_ci{ 19813498266Sopenharmony_ci CC_MD5_Final(digest, ctx); 19913498266Sopenharmony_ci} 20013498266Sopenharmony_ci 20113498266Sopenharmony_ci#elif defined(USE_WIN32_CRYPTO) 20213498266Sopenharmony_ci 20313498266Sopenharmony_cistruct md5_ctx { 20413498266Sopenharmony_ci HCRYPTPROV hCryptProv; 20513498266Sopenharmony_ci HCRYPTHASH hHash; 20613498266Sopenharmony_ci}; 20713498266Sopenharmony_citypedef struct md5_ctx my_md5_ctx; 20813498266Sopenharmony_ci 20913498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx) 21013498266Sopenharmony_ci{ 21113498266Sopenharmony_ci if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL, 21213498266Sopenharmony_ci CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 21313498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 21413498266Sopenharmony_ci 21513498266Sopenharmony_ci if(!CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash)) { 21613498266Sopenharmony_ci CryptReleaseContext(ctx->hCryptProv, 0); 21713498266Sopenharmony_ci ctx->hCryptProv = 0; 21813498266Sopenharmony_ci return CURLE_FAILED_INIT; 21913498266Sopenharmony_ci } 22013498266Sopenharmony_ci 22113498266Sopenharmony_ci return CURLE_OK; 22213498266Sopenharmony_ci} 22313498266Sopenharmony_ci 22413498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, 22513498266Sopenharmony_ci const unsigned char *input, 22613498266Sopenharmony_ci unsigned int inputLen) 22713498266Sopenharmony_ci{ 22813498266Sopenharmony_ci CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0); 22913498266Sopenharmony_ci} 23013498266Sopenharmony_ci 23113498266Sopenharmony_cistatic void my_md5_final(unsigned char *digest, my_md5_ctx *ctx) 23213498266Sopenharmony_ci{ 23313498266Sopenharmony_ci unsigned long length = 0; 23413498266Sopenharmony_ci CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); 23513498266Sopenharmony_ci if(length == 16) 23613498266Sopenharmony_ci CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); 23713498266Sopenharmony_ci if(ctx->hHash) 23813498266Sopenharmony_ci CryptDestroyHash(ctx->hHash); 23913498266Sopenharmony_ci if(ctx->hCryptProv) 24013498266Sopenharmony_ci CryptReleaseContext(ctx->hCryptProv, 0); 24113498266Sopenharmony_ci} 24213498266Sopenharmony_ci 24313498266Sopenharmony_ci#else 24413498266Sopenharmony_ci 24513498266Sopenharmony_ci/* When no other crypto library is available we use this code segment */ 24613498266Sopenharmony_ci 24713498266Sopenharmony_ci/* 24813498266Sopenharmony_ci * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 24913498266Sopenharmony_ci * MD5 Message-Digest Algorithm (RFC 1321). 25013498266Sopenharmony_ci * 25113498266Sopenharmony_ci * Homepage: 25213498266Sopenharmony_ci https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 25313498266Sopenharmony_ci * 25413498266Sopenharmony_ci * Author: 25513498266Sopenharmony_ci * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 25613498266Sopenharmony_ci * 25713498266Sopenharmony_ci * This software was written by Alexander Peslyak in 2001. No copyright is 25813498266Sopenharmony_ci * claimed, and the software is hereby placed in the public domain. 25913498266Sopenharmony_ci * In case this attempt to disclaim copyright and place the software in the 26013498266Sopenharmony_ci * public domain is deemed null and void, then the software is 26113498266Sopenharmony_ci * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 26213498266Sopenharmony_ci * general public under the following terms: 26313498266Sopenharmony_ci * 26413498266Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 26513498266Sopenharmony_ci * modification, are permitted. 26613498266Sopenharmony_ci * 26713498266Sopenharmony_ci * There's ABSOLUTELY NO WARRANTY, express or implied. 26813498266Sopenharmony_ci * 26913498266Sopenharmony_ci * (This is a heavily cut-down "BSD license".) 27013498266Sopenharmony_ci * 27113498266Sopenharmony_ci * This differs from Colin Plumb's older public domain implementation in that 27213498266Sopenharmony_ci * no exactly 32-bit integer data type is required (any 32-bit or wider 27313498266Sopenharmony_ci * unsigned integer data type will do), there's no compile-time endianness 27413498266Sopenharmony_ci * configuration, and the function prototypes match OpenSSL's. No code from 27513498266Sopenharmony_ci * Colin Plumb's implementation has been reused; this comment merely compares 27613498266Sopenharmony_ci * the properties of the two independent implementations. 27713498266Sopenharmony_ci * 27813498266Sopenharmony_ci * The primary goals of this implementation are portability and ease of use. 27913498266Sopenharmony_ci * It is meant to be fast, but not as fast as possible. Some known 28013498266Sopenharmony_ci * optimizations are not included to reduce source code size and avoid 28113498266Sopenharmony_ci * compile-time configuration. 28213498266Sopenharmony_ci */ 28313498266Sopenharmony_ci 28413498266Sopenharmony_ci/* Any 32-bit or wider unsigned integer data type will do */ 28513498266Sopenharmony_citypedef unsigned int MD5_u32plus; 28613498266Sopenharmony_ci 28713498266Sopenharmony_cistruct md5_ctx { 28813498266Sopenharmony_ci MD5_u32plus lo, hi; 28913498266Sopenharmony_ci MD5_u32plus a, b, c, d; 29013498266Sopenharmony_ci unsigned char buffer[64]; 29113498266Sopenharmony_ci MD5_u32plus block[16]; 29213498266Sopenharmony_ci}; 29313498266Sopenharmony_citypedef struct md5_ctx my_md5_ctx; 29413498266Sopenharmony_ci 29513498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx); 29613498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, const void *data, 29713498266Sopenharmony_ci unsigned long size); 29813498266Sopenharmony_cistatic void my_md5_final(unsigned char *result, my_md5_ctx *ctx); 29913498266Sopenharmony_ci 30013498266Sopenharmony_ci/* 30113498266Sopenharmony_ci * The basic MD5 functions. 30213498266Sopenharmony_ci * 30313498266Sopenharmony_ci * F and G are optimized compared to their RFC 1321 definitions for 30413498266Sopenharmony_ci * architectures that lack an AND-NOT instruction, just like in Colin Plumb's 30513498266Sopenharmony_ci * implementation. 30613498266Sopenharmony_ci */ 30713498266Sopenharmony_ci#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 30813498266Sopenharmony_ci#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 30913498266Sopenharmony_ci#define H(x, y, z) (((x) ^ (y)) ^ (z)) 31013498266Sopenharmony_ci#define H2(x, y, z) ((x) ^ ((y) ^ (z))) 31113498266Sopenharmony_ci#define I(x, y, z) ((y) ^ ((x) | ~(z))) 31213498266Sopenharmony_ci 31313498266Sopenharmony_ci/* 31413498266Sopenharmony_ci * The MD5 transformation for all four rounds. 31513498266Sopenharmony_ci */ 31613498266Sopenharmony_ci#define STEP(f, a, b, c, d, x, t, s) \ 31713498266Sopenharmony_ci (a) += f((b), (c), (d)) + (x) + (t); \ 31813498266Sopenharmony_ci (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 31913498266Sopenharmony_ci (a) += (b); 32013498266Sopenharmony_ci 32113498266Sopenharmony_ci/* 32213498266Sopenharmony_ci * SET reads 4 input bytes in little-endian byte order and stores them 32313498266Sopenharmony_ci * in a properly aligned word in host byte order. 32413498266Sopenharmony_ci * 32513498266Sopenharmony_ci * The check for little-endian architectures that tolerate unaligned 32613498266Sopenharmony_ci * memory accesses is just an optimization. Nothing will break if it 32713498266Sopenharmony_ci * doesn't work. 32813498266Sopenharmony_ci */ 32913498266Sopenharmony_ci#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 33013498266Sopenharmony_ci#define SET(n) \ 33113498266Sopenharmony_ci (*(MD5_u32plus *)(void *)&ptr[(n) * 4]) 33213498266Sopenharmony_ci#define GET(n) \ 33313498266Sopenharmony_ci SET(n) 33413498266Sopenharmony_ci#else 33513498266Sopenharmony_ci#define SET(n) \ 33613498266Sopenharmony_ci (ctx->block[(n)] = \ 33713498266Sopenharmony_ci (MD5_u32plus)ptr[(n) * 4] | \ 33813498266Sopenharmony_ci ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ 33913498266Sopenharmony_ci ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ 34013498266Sopenharmony_ci ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) 34113498266Sopenharmony_ci#define GET(n) \ 34213498266Sopenharmony_ci (ctx->block[(n)]) 34313498266Sopenharmony_ci#endif 34413498266Sopenharmony_ci 34513498266Sopenharmony_ci/* 34613498266Sopenharmony_ci * This processes one or more 64-byte data blocks, but does NOT update 34713498266Sopenharmony_ci * the bit counters. There are no alignment requirements. 34813498266Sopenharmony_ci */ 34913498266Sopenharmony_cistatic const void *body(my_md5_ctx *ctx, const void *data, unsigned long size) 35013498266Sopenharmony_ci{ 35113498266Sopenharmony_ci const unsigned char *ptr; 35213498266Sopenharmony_ci MD5_u32plus a, b, c, d; 35313498266Sopenharmony_ci 35413498266Sopenharmony_ci ptr = (const unsigned char *)data; 35513498266Sopenharmony_ci 35613498266Sopenharmony_ci a = ctx->a; 35713498266Sopenharmony_ci b = ctx->b; 35813498266Sopenharmony_ci c = ctx->c; 35913498266Sopenharmony_ci d = ctx->d; 36013498266Sopenharmony_ci 36113498266Sopenharmony_ci do { 36213498266Sopenharmony_ci MD5_u32plus saved_a, saved_b, saved_c, saved_d; 36313498266Sopenharmony_ci 36413498266Sopenharmony_ci saved_a = a; 36513498266Sopenharmony_ci saved_b = b; 36613498266Sopenharmony_ci saved_c = c; 36713498266Sopenharmony_ci saved_d = d; 36813498266Sopenharmony_ci 36913498266Sopenharmony_ci/* Round 1 */ 37013498266Sopenharmony_ci STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) 37113498266Sopenharmony_ci STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) 37213498266Sopenharmony_ci STEP(F, c, d, a, b, SET(2), 0x242070db, 17) 37313498266Sopenharmony_ci STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) 37413498266Sopenharmony_ci STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) 37513498266Sopenharmony_ci STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) 37613498266Sopenharmony_ci STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) 37713498266Sopenharmony_ci STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) 37813498266Sopenharmony_ci STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) 37913498266Sopenharmony_ci STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) 38013498266Sopenharmony_ci STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) 38113498266Sopenharmony_ci STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) 38213498266Sopenharmony_ci STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) 38313498266Sopenharmony_ci STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) 38413498266Sopenharmony_ci STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) 38513498266Sopenharmony_ci STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) 38613498266Sopenharmony_ci 38713498266Sopenharmony_ci/* Round 2 */ 38813498266Sopenharmony_ci STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) 38913498266Sopenharmony_ci STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) 39013498266Sopenharmony_ci STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) 39113498266Sopenharmony_ci STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 39213498266Sopenharmony_ci STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) 39313498266Sopenharmony_ci STEP(G, d, a, b, c, GET(10), 0x02441453, 9) 39413498266Sopenharmony_ci STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) 39513498266Sopenharmony_ci STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 39613498266Sopenharmony_ci STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) 39713498266Sopenharmony_ci STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) 39813498266Sopenharmony_ci STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) 39913498266Sopenharmony_ci STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) 40013498266Sopenharmony_ci STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) 40113498266Sopenharmony_ci STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 40213498266Sopenharmony_ci STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) 40313498266Sopenharmony_ci STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 40413498266Sopenharmony_ci 40513498266Sopenharmony_ci/* Round 3 */ 40613498266Sopenharmony_ci STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) 40713498266Sopenharmony_ci STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) 40813498266Sopenharmony_ci STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) 40913498266Sopenharmony_ci STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) 41013498266Sopenharmony_ci STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) 41113498266Sopenharmony_ci STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) 41213498266Sopenharmony_ci STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 41313498266Sopenharmony_ci STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) 41413498266Sopenharmony_ci STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) 41513498266Sopenharmony_ci STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) 41613498266Sopenharmony_ci STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) 41713498266Sopenharmony_ci STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) 41813498266Sopenharmony_ci STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) 41913498266Sopenharmony_ci STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) 42013498266Sopenharmony_ci STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 42113498266Sopenharmony_ci STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) 42213498266Sopenharmony_ci 42313498266Sopenharmony_ci/* Round 4 */ 42413498266Sopenharmony_ci STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) 42513498266Sopenharmony_ci STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) 42613498266Sopenharmony_ci STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) 42713498266Sopenharmony_ci STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) 42813498266Sopenharmony_ci STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) 42913498266Sopenharmony_ci STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 43013498266Sopenharmony_ci STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) 43113498266Sopenharmony_ci STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) 43213498266Sopenharmony_ci STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 43313498266Sopenharmony_ci STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 43413498266Sopenharmony_ci STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) 43513498266Sopenharmony_ci STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) 43613498266Sopenharmony_ci STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) 43713498266Sopenharmony_ci STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) 43813498266Sopenharmony_ci STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 43913498266Sopenharmony_ci STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) 44013498266Sopenharmony_ci 44113498266Sopenharmony_ci a += saved_a; 44213498266Sopenharmony_ci b += saved_b; 44313498266Sopenharmony_ci c += saved_c; 44413498266Sopenharmony_ci d += saved_d; 44513498266Sopenharmony_ci 44613498266Sopenharmony_ci ptr += 64; 44713498266Sopenharmony_ci } while(size -= 64); 44813498266Sopenharmony_ci 44913498266Sopenharmony_ci ctx->a = a; 45013498266Sopenharmony_ci ctx->b = b; 45113498266Sopenharmony_ci ctx->c = c; 45213498266Sopenharmony_ci ctx->d = d; 45313498266Sopenharmony_ci 45413498266Sopenharmony_ci return ptr; 45513498266Sopenharmony_ci} 45613498266Sopenharmony_ci 45713498266Sopenharmony_cistatic CURLcode my_md5_init(my_md5_ctx *ctx) 45813498266Sopenharmony_ci{ 45913498266Sopenharmony_ci ctx->a = 0x67452301; 46013498266Sopenharmony_ci ctx->b = 0xefcdab89; 46113498266Sopenharmony_ci ctx->c = 0x98badcfe; 46213498266Sopenharmony_ci ctx->d = 0x10325476; 46313498266Sopenharmony_ci 46413498266Sopenharmony_ci ctx->lo = 0; 46513498266Sopenharmony_ci ctx->hi = 0; 46613498266Sopenharmony_ci 46713498266Sopenharmony_ci return CURLE_OK; 46813498266Sopenharmony_ci} 46913498266Sopenharmony_ci 47013498266Sopenharmony_cistatic void my_md5_update(my_md5_ctx *ctx, const void *data, 47113498266Sopenharmony_ci unsigned long size) 47213498266Sopenharmony_ci{ 47313498266Sopenharmony_ci MD5_u32plus saved_lo; 47413498266Sopenharmony_ci unsigned long used; 47513498266Sopenharmony_ci 47613498266Sopenharmony_ci saved_lo = ctx->lo; 47713498266Sopenharmony_ci ctx->lo = (saved_lo + size) & 0x1fffffff; 47813498266Sopenharmony_ci if(ctx->lo < saved_lo) 47913498266Sopenharmony_ci ctx->hi++; 48013498266Sopenharmony_ci ctx->hi += (MD5_u32plus)size >> 29; 48113498266Sopenharmony_ci 48213498266Sopenharmony_ci used = saved_lo & 0x3f; 48313498266Sopenharmony_ci 48413498266Sopenharmony_ci if(used) { 48513498266Sopenharmony_ci unsigned long available = 64 - used; 48613498266Sopenharmony_ci 48713498266Sopenharmony_ci if(size < available) { 48813498266Sopenharmony_ci memcpy(&ctx->buffer[used], data, size); 48913498266Sopenharmony_ci return; 49013498266Sopenharmony_ci } 49113498266Sopenharmony_ci 49213498266Sopenharmony_ci memcpy(&ctx->buffer[used], data, available); 49313498266Sopenharmony_ci data = (const unsigned char *)data + available; 49413498266Sopenharmony_ci size -= available; 49513498266Sopenharmony_ci body(ctx, ctx->buffer, 64); 49613498266Sopenharmony_ci } 49713498266Sopenharmony_ci 49813498266Sopenharmony_ci if(size >= 64) { 49913498266Sopenharmony_ci data = body(ctx, data, size & ~(unsigned long)0x3f); 50013498266Sopenharmony_ci size &= 0x3f; 50113498266Sopenharmony_ci } 50213498266Sopenharmony_ci 50313498266Sopenharmony_ci memcpy(ctx->buffer, data, size); 50413498266Sopenharmony_ci} 50513498266Sopenharmony_ci 50613498266Sopenharmony_cistatic void my_md5_final(unsigned char *result, my_md5_ctx *ctx) 50713498266Sopenharmony_ci{ 50813498266Sopenharmony_ci unsigned long used, available; 50913498266Sopenharmony_ci 51013498266Sopenharmony_ci used = ctx->lo & 0x3f; 51113498266Sopenharmony_ci 51213498266Sopenharmony_ci ctx->buffer[used++] = 0x80; 51313498266Sopenharmony_ci 51413498266Sopenharmony_ci available = 64 - used; 51513498266Sopenharmony_ci 51613498266Sopenharmony_ci if(available < 8) { 51713498266Sopenharmony_ci memset(&ctx->buffer[used], 0, available); 51813498266Sopenharmony_ci body(ctx, ctx->buffer, 64); 51913498266Sopenharmony_ci used = 0; 52013498266Sopenharmony_ci available = 64; 52113498266Sopenharmony_ci } 52213498266Sopenharmony_ci 52313498266Sopenharmony_ci memset(&ctx->buffer[used], 0, available - 8); 52413498266Sopenharmony_ci 52513498266Sopenharmony_ci ctx->lo <<= 3; 52613498266Sopenharmony_ci ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff); 52713498266Sopenharmony_ci ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff); 52813498266Sopenharmony_ci ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff); 52913498266Sopenharmony_ci ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24); 53013498266Sopenharmony_ci ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff); 53113498266Sopenharmony_ci ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff); 53213498266Sopenharmony_ci ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff); 53313498266Sopenharmony_ci ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); 53413498266Sopenharmony_ci 53513498266Sopenharmony_ci body(ctx, ctx->buffer, 64); 53613498266Sopenharmony_ci 53713498266Sopenharmony_ci result[0] = curlx_ultouc((ctx->a)&0xff); 53813498266Sopenharmony_ci result[1] = curlx_ultouc((ctx->a >> 8)&0xff); 53913498266Sopenharmony_ci result[2] = curlx_ultouc((ctx->a >> 16)&0xff); 54013498266Sopenharmony_ci result[3] = curlx_ultouc(ctx->a >> 24); 54113498266Sopenharmony_ci result[4] = curlx_ultouc((ctx->b)&0xff); 54213498266Sopenharmony_ci result[5] = curlx_ultouc((ctx->b >> 8)&0xff); 54313498266Sopenharmony_ci result[6] = curlx_ultouc((ctx->b >> 16)&0xff); 54413498266Sopenharmony_ci result[7] = curlx_ultouc(ctx->b >> 24); 54513498266Sopenharmony_ci result[8] = curlx_ultouc((ctx->c)&0xff); 54613498266Sopenharmony_ci result[9] = curlx_ultouc((ctx->c >> 8)&0xff); 54713498266Sopenharmony_ci result[10] = curlx_ultouc((ctx->c >> 16)&0xff); 54813498266Sopenharmony_ci result[11] = curlx_ultouc(ctx->c >> 24); 54913498266Sopenharmony_ci result[12] = curlx_ultouc((ctx->d)&0xff); 55013498266Sopenharmony_ci result[13] = curlx_ultouc((ctx->d >> 8)&0xff); 55113498266Sopenharmony_ci result[14] = curlx_ultouc((ctx->d >> 16)&0xff); 55213498266Sopenharmony_ci result[15] = curlx_ultouc(ctx->d >> 24); 55313498266Sopenharmony_ci 55413498266Sopenharmony_ci memset(ctx, 0, sizeof(*ctx)); 55513498266Sopenharmony_ci} 55613498266Sopenharmony_ci 55713498266Sopenharmony_ci#endif /* CRYPTO LIBS */ 55813498266Sopenharmony_ci 55913498266Sopenharmony_ciconst struct HMAC_params Curl_HMAC_MD5[] = { 56013498266Sopenharmony_ci { 56113498266Sopenharmony_ci /* Hash initialization function. */ 56213498266Sopenharmony_ci CURLX_FUNCTION_CAST(HMAC_hinit_func, my_md5_init), 56313498266Sopenharmony_ci /* Hash update function. */ 56413498266Sopenharmony_ci CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_md5_update), 56513498266Sopenharmony_ci /* Hash computation end function. */ 56613498266Sopenharmony_ci CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_md5_final), 56713498266Sopenharmony_ci /* Size of hash context structure. */ 56813498266Sopenharmony_ci sizeof(my_md5_ctx), 56913498266Sopenharmony_ci /* Maximum key length. */ 57013498266Sopenharmony_ci 64, 57113498266Sopenharmony_ci /* Result size. */ 57213498266Sopenharmony_ci 16 57313498266Sopenharmony_ci } 57413498266Sopenharmony_ci}; 57513498266Sopenharmony_ci 57613498266Sopenharmony_ciconst struct MD5_params Curl_DIGEST_MD5[] = { 57713498266Sopenharmony_ci { 57813498266Sopenharmony_ci /* Digest initialization function */ 57913498266Sopenharmony_ci CURLX_FUNCTION_CAST(Curl_MD5_init_func, my_md5_init), 58013498266Sopenharmony_ci /* Digest update function */ 58113498266Sopenharmony_ci CURLX_FUNCTION_CAST(Curl_MD5_update_func, my_md5_update), 58213498266Sopenharmony_ci /* Digest computation end function */ 58313498266Sopenharmony_ci CURLX_FUNCTION_CAST(Curl_MD5_final_func, my_md5_final), 58413498266Sopenharmony_ci /* Size of digest context struct */ 58513498266Sopenharmony_ci sizeof(my_md5_ctx), 58613498266Sopenharmony_ci /* Result size */ 58713498266Sopenharmony_ci 16 58813498266Sopenharmony_ci } 58913498266Sopenharmony_ci}; 59013498266Sopenharmony_ci 59113498266Sopenharmony_ci/* 59213498266Sopenharmony_ci * @unittest: 1601 59313498266Sopenharmony_ci * Returns CURLE_OK on success. 59413498266Sopenharmony_ci */ 59513498266Sopenharmony_ciCURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input, 59613498266Sopenharmony_ci const size_t len) 59713498266Sopenharmony_ci{ 59813498266Sopenharmony_ci CURLcode result; 59913498266Sopenharmony_ci my_md5_ctx ctx; 60013498266Sopenharmony_ci 60113498266Sopenharmony_ci result = my_md5_init(&ctx); 60213498266Sopenharmony_ci if(!result) { 60313498266Sopenharmony_ci my_md5_update(&ctx, input, curlx_uztoui(len)); 60413498266Sopenharmony_ci my_md5_final(outbuffer, &ctx); 60513498266Sopenharmony_ci } 60613498266Sopenharmony_ci return result; 60713498266Sopenharmony_ci} 60813498266Sopenharmony_ci 60913498266Sopenharmony_cistruct MD5_context *Curl_MD5_init(const struct MD5_params *md5params) 61013498266Sopenharmony_ci{ 61113498266Sopenharmony_ci struct MD5_context *ctxt; 61213498266Sopenharmony_ci 61313498266Sopenharmony_ci /* Create MD5 context */ 61413498266Sopenharmony_ci ctxt = malloc(sizeof(*ctxt)); 61513498266Sopenharmony_ci 61613498266Sopenharmony_ci if(!ctxt) 61713498266Sopenharmony_ci return ctxt; 61813498266Sopenharmony_ci 61913498266Sopenharmony_ci ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize); 62013498266Sopenharmony_ci 62113498266Sopenharmony_ci if(!ctxt->md5_hashctx) { 62213498266Sopenharmony_ci free(ctxt); 62313498266Sopenharmony_ci return NULL; 62413498266Sopenharmony_ci } 62513498266Sopenharmony_ci 62613498266Sopenharmony_ci ctxt->md5_hash = md5params; 62713498266Sopenharmony_ci 62813498266Sopenharmony_ci if((*md5params->md5_init_func)(ctxt->md5_hashctx)) { 62913498266Sopenharmony_ci free(ctxt->md5_hashctx); 63013498266Sopenharmony_ci free(ctxt); 63113498266Sopenharmony_ci return NULL; 63213498266Sopenharmony_ci } 63313498266Sopenharmony_ci 63413498266Sopenharmony_ci return ctxt; 63513498266Sopenharmony_ci} 63613498266Sopenharmony_ci 63713498266Sopenharmony_ciCURLcode Curl_MD5_update(struct MD5_context *context, 63813498266Sopenharmony_ci const unsigned char *data, 63913498266Sopenharmony_ci unsigned int len) 64013498266Sopenharmony_ci{ 64113498266Sopenharmony_ci (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len); 64213498266Sopenharmony_ci 64313498266Sopenharmony_ci return CURLE_OK; 64413498266Sopenharmony_ci} 64513498266Sopenharmony_ci 64613498266Sopenharmony_ciCURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result) 64713498266Sopenharmony_ci{ 64813498266Sopenharmony_ci (*context->md5_hash->md5_final_func)(result, context->md5_hashctx); 64913498266Sopenharmony_ci 65013498266Sopenharmony_ci free(context->md5_hashctx); 65113498266Sopenharmony_ci free(context); 65213498266Sopenharmony_ci 65313498266Sopenharmony_ci return CURLE_OK; 65413498266Sopenharmony_ci} 65513498266Sopenharmony_ci 65613498266Sopenharmony_ci#endif /* Using NTLM (without SSPI) || Digest */ 657