Annotation of embedaddon/curl/lib/md5.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>