Annotation of embedaddon/curl/lib/md5.c, revision 1.1.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>