File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / md5.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    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>