00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #ifndef CURL_DISABLE_CRYPTO_AUTH
00026
00027 #include <curl/curl.h>
00028
00029 #include "curl_md5.h"
00030 #include "curl_hmac.h"
00031 #include "warnless.h"
00032
00033 #if defined(USE_GNUTLS_NETTLE)
00034
00035 #include <nettle/md5.h>
00036 #include "curl_memory.h"
00037
00038 #include "memdebug.h"
00039
00040 typedef struct md5_ctx MD5_CTX;
00041
00042 static void MD5_Init(MD5_CTX * ctx)
00043 {
00044 md5_init(ctx);
00045 }
00046
00047 static void MD5_Update(MD5_CTX * ctx,
00048 const unsigned char *input,
00049 unsigned int inputLen)
00050 {
00051 md5_update(ctx, inputLen, input);
00052 }
00053
00054 static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
00055 {
00056 md5_digest(ctx, 16, digest);
00057 }
00058
00059 #elif defined(USE_GNUTLS)
00060
00061 #include <gcrypt.h>
00062 #include "curl_memory.h"
00063
00064 #include "memdebug.h"
00065
00066 typedef gcry_md_hd_t MD5_CTX;
00067
00068 static void MD5_Init(MD5_CTX * ctx)
00069 {
00070 gcry_md_open(ctx, GCRY_MD_MD5, 0);
00071 }
00072
00073 static void MD5_Update(MD5_CTX * ctx,
00074 const unsigned char *input,
00075 unsigned int inputLen)
00076 {
00077 gcry_md_write(*ctx, input, inputLen);
00078 }
00079
00080 static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
00081 {
00082 memcpy(digest, gcry_md_read(*ctx, 0), 16);
00083 gcry_md_close(*ctx);
00084 }
00085
00086 #elif defined(USE_OPENSSL)
00087
00088 #include <openssl/md5.h>
00089 #include "curl_memory.h"
00090
00091 #include "memdebug.h"
00092
00093 #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
00094 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
00095 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
00096 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
00097
00098
00099
00100
00101
00102
00103
00104 # include <CommonCrypto/CommonDigest.h>
00105 # define MD5_CTX CC_MD5_CTX
00106 #include "curl_memory.h"
00107
00108 #include "memdebug.h"
00109
00110 static void MD5_Init(MD5_CTX *ctx)
00111 {
00112 CC_MD5_Init(ctx);
00113 }
00114
00115 static void MD5_Update(MD5_CTX *ctx,
00116 const unsigned char *input,
00117 unsigned int inputLen)
00118 {
00119 CC_MD5_Update(ctx, input, inputLen);
00120 }
00121
00122 static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
00123 {
00124 CC_MD5_Final(digest, ctx);
00125 }
00126
00127 #elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
00128
00129 #include <wincrypt.h>
00130 #include "curl_memory.h"
00131
00132 #include "memdebug.h"
00133
00134 typedef struct {
00135 HCRYPTPROV hCryptProv;
00136 HCRYPTHASH hHash;
00137 } MD5_CTX;
00138
00139 static void MD5_Init(MD5_CTX *ctx)
00140 {
00141 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
00142 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
00143 CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
00144 }
00145 }
00146
00147 static void MD5_Update(MD5_CTX *ctx,
00148 const unsigned char *input,
00149 unsigned int inputLen)
00150 {
00151 CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
00152 }
00153
00154 static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
00155 {
00156 unsigned long length = 0;
00157 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
00158 if(length == 16)
00159 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
00160 if(ctx->hHash)
00161 CryptDestroyHash(ctx->hHash);
00162 if(ctx->hCryptProv)
00163 CryptReleaseContext(ctx->hCryptProv, 0);
00164 }
00165
00166 #elif defined(USE_AXTLS)
00167 #include <axTLS/config.h>
00168 #include <axTLS/os_int.h>
00169 #include <axTLS/crypto.h>
00170 #include "curl_memory.h"
00171
00172 #include "memdebug.h"
00173 #else
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 #include <string.h>
00213
00214
00215 #include "curl_memory.h"
00216 #include "memdebug.h"
00217
00218
00219 typedef unsigned int MD5_u32plus;
00220
00221 typedef struct {
00222 MD5_u32plus lo, hi;
00223 MD5_u32plus a, b, c, d;
00224 unsigned char buffer[64];
00225 MD5_u32plus block[16];
00226 } MD5_CTX;
00227
00228 static void MD5_Init(MD5_CTX *ctx);
00229 static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
00230 static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
00231
00232
00233
00234
00235
00236
00237
00238
00239 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
00240 #define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
00241 #define H(x, y, z) (((x) ^ (y)) ^ (z))
00242 #define H2(x, y, z) ((x) ^ ((y) ^ (z)))
00243 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
00244
00245
00246
00247
00248 #define STEP(f, a, b, c, d, x, t, s) \
00249 (a) += f((b), (c), (d)) + (x) + (t); \
00250 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
00251 (a) += (b);
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
00262 #define SET(n) \
00263 (*(MD5_u32plus *)&ptr[(n) * 4])
00264 #define GET(n) \
00265 SET(n)
00266 #else
00267 #define SET(n) \
00268 (ctx->block[(n)] = \
00269 (MD5_u32plus)ptr[(n) * 4] | \
00270 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
00271 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
00272 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
00273 #define GET(n) \
00274 (ctx->block[(n)])
00275 #endif
00276
00277
00278
00279
00280
00281 static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
00282 {
00283 const unsigned char *ptr;
00284 MD5_u32plus a, b, c, d;
00285 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
00286
00287 ptr = (const unsigned char *)data;
00288
00289 a = ctx->a;
00290 b = ctx->b;
00291 c = ctx->c;
00292 d = ctx->d;
00293
00294 do {
00295 saved_a = a;
00296 saved_b = b;
00297 saved_c = c;
00298 saved_d = d;
00299
00300
00301 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
00302 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
00303 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
00304 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
00305 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
00306 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
00307 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
00308 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
00309 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
00310 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
00311 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
00312 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
00313 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
00314 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
00315 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
00316 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
00317
00318
00319 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
00320 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
00321 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
00322 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
00323 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
00324 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
00325 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
00326 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
00327 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
00328 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
00329 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
00330 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
00331 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
00332 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
00333 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
00334 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
00335
00336
00337 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
00338 STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
00339 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
00340 STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
00341 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
00342 STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
00343 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
00344 STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
00345 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
00346 STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
00347 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
00348 STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
00349 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
00350 STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
00351 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
00352 STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
00353
00354
00355 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
00356 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
00357 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
00358 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
00359 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
00360 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
00361 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
00362 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
00363 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
00364 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
00365 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
00366 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
00367 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
00368 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
00369 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
00370 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
00371
00372 a += saved_a;
00373 b += saved_b;
00374 c += saved_c;
00375 d += saved_d;
00376
00377 ptr += 64;
00378 } while(size -= 64);
00379
00380 ctx->a = a;
00381 ctx->b = b;
00382 ctx->c = c;
00383 ctx->d = d;
00384
00385 return ptr;
00386 }
00387
00388 static void MD5_Init(MD5_CTX *ctx)
00389 {
00390 ctx->a = 0x67452301;
00391 ctx->b = 0xefcdab89;
00392 ctx->c = 0x98badcfe;
00393 ctx->d = 0x10325476;
00394
00395 ctx->lo = 0;
00396 ctx->hi = 0;
00397 }
00398
00399 static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
00400 {
00401 MD5_u32plus saved_lo;
00402 unsigned long used, available;
00403
00404 saved_lo = ctx->lo;
00405 ctx->lo = (saved_lo + size) & 0x1fffffff;
00406 if(ctx->lo < saved_lo)
00407 ctx->hi++;
00408 ctx->hi += (MD5_u32plus)size >> 29;
00409
00410 used = saved_lo & 0x3f;
00411
00412 if(used) {
00413 available = 64 - used;
00414
00415 if(size < available) {
00416 memcpy(&ctx->buffer[used], data, size);
00417 return;
00418 }
00419
00420 memcpy(&ctx->buffer[used], data, available);
00421 data = (const unsigned char *)data + available;
00422 size -= available;
00423 body(ctx, ctx->buffer, 64);
00424 }
00425
00426 if(size >= 64) {
00427 data = body(ctx, data, size & ~(unsigned long)0x3f);
00428 size &= 0x3f;
00429 }
00430
00431 memcpy(ctx->buffer, data, size);
00432 }
00433
00434 static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
00435 {
00436 unsigned long used, available;
00437
00438 used = ctx->lo & 0x3f;
00439
00440 ctx->buffer[used++] = 0x80;
00441
00442 available = 64 - used;
00443
00444 if(available < 8) {
00445 memset(&ctx->buffer[used], 0, available);
00446 body(ctx, ctx->buffer, 64);
00447 used = 0;
00448 available = 64;
00449 }
00450
00451 memset(&ctx->buffer[used], 0, available - 8);
00452
00453 ctx->lo <<= 3;
00454 ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
00455 ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
00456 ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
00457 ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
00458 ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
00459 ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
00460 ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
00461 ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
00462
00463 body(ctx, ctx->buffer, 64);
00464
00465 result[0] = curlx_ultouc((ctx->a)&0xff);
00466 result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
00467 result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
00468 result[3] = curlx_ultouc(ctx->a >> 24);
00469 result[4] = curlx_ultouc((ctx->b)&0xff);
00470 result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
00471 result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
00472 result[7] = curlx_ultouc(ctx->b >> 24);
00473 result[8] = curlx_ultouc((ctx->c)&0xff);
00474 result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
00475 result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
00476 result[11] = curlx_ultouc(ctx->c >> 24);
00477 result[12] = curlx_ultouc((ctx->d)&0xff);
00478 result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
00479 result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
00480 result[15] = curlx_ultouc(ctx->d >> 24);
00481
00482 memset(ctx, 0, sizeof(*ctx));
00483 }
00484
00485 #endif
00486
00487 const HMAC_params Curl_HMAC_MD5[] = {
00488 {
00489 (HMAC_hinit_func) MD5_Init,
00490 (HMAC_hupdate_func) MD5_Update,
00491 (HMAC_hfinal_func) MD5_Final,
00492 sizeof(MD5_CTX),
00493 64,
00494 16
00495 }
00496 };
00497
00498 const MD5_params Curl_DIGEST_MD5[] = {
00499 {
00500 (Curl_MD5_init_func) MD5_Init,
00501 (Curl_MD5_update_func) MD5_Update,
00502 (Curl_MD5_final_func) MD5_Final,
00503 sizeof(MD5_CTX),
00504 16
00505 }
00506 };
00507
00508
00509
00510
00511 void Curl_md5it(unsigned char *outbuffer,
00512 const unsigned char *input)
00513 {
00514 MD5_CTX ctx;
00515 MD5_Init(&ctx);
00516 MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
00517 MD5_Final(outbuffer, &ctx);
00518 }
00519
00520 MD5_context *Curl_MD5_init(const MD5_params *md5params)
00521 {
00522 MD5_context *ctxt;
00523
00524
00525 ctxt = malloc(sizeof *ctxt);
00526
00527 if(!ctxt)
00528 return ctxt;
00529
00530 ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
00531
00532 if(!ctxt->md5_hashctx) {
00533 free(ctxt);
00534 return NULL;
00535 }
00536
00537 ctxt->md5_hash = md5params;
00538
00539 (*md5params->md5_init_func)(ctxt->md5_hashctx);
00540
00541 return ctxt;
00542 }
00543
00544 int Curl_MD5_update(MD5_context *context,
00545 const unsigned char *data,
00546 unsigned int len)
00547 {
00548 (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
00549
00550 return 0;
00551 }
00552
00553 int Curl_MD5_final(MD5_context *context, unsigned char *result)
00554 {
00555 (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
00556
00557 free(context->md5_hashctx);
00558 free(context);
00559
00560 return 0;
00561 }
00562
00563 #endif