File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / md4.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: #if !defined(CURL_DISABLE_CRYPTO_AUTH)
   26: 
   27: #include "curl_md4.h"
   28: #include "warnless.h"
   29: 
   30: #ifdef USE_OPENSSL
   31: #include <openssl/opensslconf.h>
   32: #if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
   33: /* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
   34: #define OPENSSL_NO_MD4
   35: #endif
   36: #endif /* USE_OPENSSL */
   37: 
   38: #ifdef USE_MBEDTLS
   39: #include <mbedtls/config.h>
   40: #include <mbedtls/version.h>
   41: 
   42: #if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
   43:   #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
   44: #endif
   45: #endif /* USE_MBEDTLS */
   46: 
   47: #if defined(USE_GNUTLS_NETTLE)
   48: 
   49: #include <nettle/md4.h>
   50: 
   51: #include "curl_memory.h"
   52: 
   53: /* The last #include file should be: */
   54: #include "memdebug.h"
   55: 
   56: typedef struct md4_ctx MD4_CTX;
   57: 
   58: static void MD4_Init(MD4_CTX *ctx)
   59: {
   60:   md4_init(ctx);
   61: }
   62: 
   63: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
   64: {
   65:   md4_update(ctx, size, data);
   66: }
   67: 
   68: static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
   69: {
   70:   md4_digest(ctx, MD4_DIGEST_SIZE, result);
   71: }
   72: 
   73: #elif defined(USE_GNUTLS)
   74: 
   75: #include <gcrypt.h>
   76: 
   77: #include "curl_memory.h"
   78: 
   79: /* The last #include file should be: */
   80: #include "memdebug.h"
   81: 
   82: typedef gcry_md_hd_t MD4_CTX;
   83: 
   84: static void MD4_Init(MD4_CTX *ctx)
   85: {
   86:   gcry_md_open(ctx, GCRY_MD_MD4, 0);
   87: }
   88: 
   89: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
   90: {
   91:   gcry_md_write(*ctx, data, size);
   92: }
   93: 
   94: static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
   95: {
   96:   memcpy(result, gcry_md_read(*ctx, 0), MD4_DIGEST_LENGTH);
   97:   gcry_md_close(*ctx);
   98: }
   99: 
  100: #elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
  101: /* When OpenSSL is available we use the MD4-functions from OpenSSL */
  102: #include <openssl/md4.h>
  103: 
  104: #elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
  105:               (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
  106:       (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
  107:               (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
  108: 
  109: #include <CommonCrypto/CommonDigest.h>
  110: 
  111: #include "curl_memory.h"
  112: 
  113: /* The last #include file should be: */
  114: #include "memdebug.h"
  115: 
  116: typedef CC_MD4_CTX MD4_CTX;
  117: 
  118: static void MD4_Init(MD4_CTX *ctx)
  119: {
  120:   (void)CC_MD4_Init(ctx);
  121: }
  122: 
  123: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
  124: {
  125:   (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
  126: }
  127: 
  128: static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
  129: {
  130:   (void)CC_MD4_Final(result, ctx);
  131: }
  132: 
  133: #elif defined(USE_WIN32_CRYPTO)
  134: 
  135: #include <wincrypt.h>
  136: 
  137: #include "curl_memory.h"
  138: 
  139: /* The last #include file should be: */
  140: #include "memdebug.h"
  141: 
  142: typedef struct {
  143:   HCRYPTPROV hCryptProv;
  144:   HCRYPTHASH hHash;
  145: } MD4_CTX;
  146: 
  147: static void MD4_Init(MD4_CTX *ctx)
  148: {
  149:   ctx->hCryptProv = 0;
  150:   ctx->hHash = 0;
  151: 
  152:   if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
  153:                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
  154:     CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
  155:   }
  156: }
  157: 
  158: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
  159: {
  160:   CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
  161: }
  162: 
  163: static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
  164: {
  165:   unsigned long length = 0;
  166: 
  167:   CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
  168:   if(length == MD4_DIGEST_LENGTH)
  169:     CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
  170: 
  171:   if(ctx->hHash)
  172:     CryptDestroyHash(ctx->hHash);
  173: 
  174:   if(ctx->hCryptProv)
  175:     CryptReleaseContext(ctx->hCryptProv, 0);
  176: }
  177: 
  178: #elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
  179: 
  180: #include <mbedtls/md4.h>
  181: 
  182: #include "curl_memory.h"
  183: 
  184: /* The last #include file should be: */
  185: #include "memdebug.h"
  186: 
  187: typedef struct {
  188:   void *data;
  189:   unsigned long size;
  190: } MD4_CTX;
  191: 
  192: static void MD4_Init(MD4_CTX *ctx)
  193: {
  194:   ctx->data = NULL;
  195:   ctx->size = 0;
  196: }
  197: 
  198: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
  199: {
  200:   if(ctx->data == NULL) {
  201:     ctx->data = malloc(size);
  202:     if(ctx->data != NULL) {
  203:       memcpy(ctx->data, data, size);
  204:       ctx->size = size;
  205:     }
  206:   }
  207: }
  208: 
  209: static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
  210: {
  211:   if(ctx->data != NULL) {
  212: #if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
  213:     mbedtls_md4(ctx->data, ctx->size, result);
  214: #else
  215:     (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
  216: #endif
  217: 
  218:     Curl_safefree(ctx->data);
  219:     ctx->size = 0;
  220:   }
  221: }
  222: 
  223: #else
  224: /* When no other crypto library is available, or the crypto library doesn't
  225:  * support MD4, we use this code segment this implementation of it
  226:  *
  227:  * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
  228:  * MD4 Message-Digest Algorithm (RFC 1320).
  229:  *
  230:  * Homepage:
  231:  https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
  232:  *
  233:  * Author:
  234:  * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
  235:  *
  236:  * This software was written by Alexander Peslyak in 2001.  No copyright is
  237:  * claimed, and the software is hereby placed in the public domain.  In case
  238:  * this attempt to disclaim copyright and place the software in the public
  239:  * domain is deemed null and void, then the software is Copyright (c) 2001
  240:  * Alexander Peslyak and it is hereby released to the general public under the
  241:  * following terms:
  242:  *
  243:  * Redistribution and use in source and binary forms, with or without
  244:  * modification, are permitted.
  245:  *
  246:  * There's ABSOLUTELY NO WARRANTY, express or implied.
  247:  *
  248:  * (This is a heavily cut-down "BSD license".)
  249:  *
  250:  * This differs from Colin Plumb's older public domain implementation in that
  251:  * no exactly 32-bit integer data type is required (any 32-bit or wider
  252:  * unsigned integer data type will do), there's no compile-time endianness
  253:  * configuration, and the function prototypes match OpenSSL's.  No code from
  254:  * Colin Plumb's implementation has been reused; this comment merely compares
  255:  * the properties of the two independent implementations.
  256:  *
  257:  * The primary goals of this implementation are portability and ease of use.
  258:  * It is meant to be fast, but not as fast as possible.  Some known
  259:  * optimizations are not included to reduce source code size and avoid
  260:  * compile-time configuration.
  261:  */
  262: 
  263: 
  264: #include <string.h>
  265: 
  266: /* Any 32-bit or wider unsigned integer data type will do */
  267: typedef unsigned int MD4_u32plus;
  268: 
  269: typedef struct {
  270:   MD4_u32plus lo, hi;
  271:   MD4_u32plus a, b, c, d;
  272:   unsigned char buffer[64];
  273:   MD4_u32plus block[16];
  274: } MD4_CTX;
  275: 
  276: static void MD4_Init(MD4_CTX *ctx);
  277: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
  278: static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
  279: 
  280: /*
  281:  * The basic MD4 functions.
  282:  *
  283:  * F and G are optimized compared to their RFC 1320 definitions, with the
  284:  * optimization for F borrowed from Colin Plumb's MD5 implementation.
  285:  */
  286: #define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
  287: #define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
  288: #define H(x, y, z)                      ((x) ^ (y) ^ (z))
  289: 
  290: /*
  291:  * The MD4 transformation for all three rounds.
  292:  */
  293: #define STEP(f, a, b, c, d, x, s) \
  294:         (a) += f((b), (c), (d)) + (x); \
  295:         (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
  296: 
  297: /*
  298:  * SET reads 4 input bytes in little-endian byte order and stores them
  299:  * in a properly aligned word in host byte order.
  300:  *
  301:  * The check for little-endian architectures that tolerate unaligned
  302:  * memory accesses is just an optimization.  Nothing will break if it
  303:  * doesn't work.
  304:  */
  305: #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
  306: #define SET(n) \
  307:         (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
  308: #define GET(n) \
  309:         SET(n)
  310: #else
  311: #define SET(n) \
  312:         (ctx->block[(n)] = \
  313:         (MD4_u32plus)ptr[(n) * 4] | \
  314:         ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
  315:         ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
  316:         ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
  317: #define GET(n) \
  318:         (ctx->block[(n)])
  319: #endif
  320: 
  321: /*
  322:  * This processes one or more 64-byte data blocks, but does NOT update
  323:  * the bit counters.  There are no alignment requirements.
  324:  */
  325: static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
  326: {
  327:   const unsigned char *ptr;
  328:   MD4_u32plus a, b, c, d;
  329: 
  330:   ptr = (const unsigned char *)data;
  331: 
  332:   a = ctx->a;
  333:   b = ctx->b;
  334:   c = ctx->c;
  335:   d = ctx->d;
  336: 
  337:   do {
  338:     MD4_u32plus saved_a, saved_b, saved_c, saved_d;
  339: 
  340:     saved_a = a;
  341:     saved_b = b;
  342:     saved_c = c;
  343:     saved_d = d;
  344: 
  345: /* Round 1 */
  346:     STEP(F, a, b, c, d, SET(0), 3)
  347:     STEP(F, d, a, b, c, SET(1), 7)
  348:     STEP(F, c, d, a, b, SET(2), 11)
  349:     STEP(F, b, c, d, a, SET(3), 19)
  350:     STEP(F, a, b, c, d, SET(4), 3)
  351:     STEP(F, d, a, b, c, SET(5), 7)
  352:     STEP(F, c, d, a, b, SET(6), 11)
  353:     STEP(F, b, c, d, a, SET(7), 19)
  354:     STEP(F, a, b, c, d, SET(8), 3)
  355:     STEP(F, d, a, b, c, SET(9), 7)
  356:     STEP(F, c, d, a, b, SET(10), 11)
  357:     STEP(F, b, c, d, a, SET(11), 19)
  358:     STEP(F, a, b, c, d, SET(12), 3)
  359:     STEP(F, d, a, b, c, SET(13), 7)
  360:     STEP(F, c, d, a, b, SET(14), 11)
  361:     STEP(F, b, c, d, a, SET(15), 19)
  362: 
  363: /* Round 2 */
  364:     STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
  365:     STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
  366:     STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
  367:     STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
  368:     STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
  369:     STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
  370:     STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
  371:     STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
  372:     STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
  373:     STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
  374:     STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
  375:     STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
  376:     STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
  377:     STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
  378:     STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
  379:     STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
  380: 
  381: /* Round 3 */
  382:     STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
  383:     STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
  384:     STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
  385:     STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
  386:     STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
  387:     STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
  388:     STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
  389:     STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
  390:     STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
  391:     STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
  392:     STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
  393:     STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
  394:     STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
  395:     STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
  396:     STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
  397:     STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
  398: 
  399:     a += saved_a;
  400:     b += saved_b;
  401:     c += saved_c;
  402:     d += saved_d;
  403: 
  404:     ptr += 64;
  405:   } while(size -= 64);
  406: 
  407:   ctx->a = a;
  408:   ctx->b = b;
  409:   ctx->c = c;
  410:   ctx->d = d;
  411: 
  412:   return ptr;
  413: }
  414: 
  415: static void MD4_Init(MD4_CTX *ctx)
  416: {
  417:   ctx->a = 0x67452301;
  418:   ctx->b = 0xefcdab89;
  419:   ctx->c = 0x98badcfe;
  420:   ctx->d = 0x10325476;
  421: 
  422:   ctx->lo = 0;
  423:   ctx->hi = 0;
  424: }
  425: 
  426: static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
  427: {
  428:   MD4_u32plus saved_lo;
  429:   unsigned long used;
  430: 
  431:   saved_lo = ctx->lo;
  432:   ctx->lo = (saved_lo + size) & 0x1fffffff;
  433:   if(ctx->lo < saved_lo)
  434:     ctx->hi++;
  435:   ctx->hi += (MD4_u32plus)size >> 29;
  436: 
  437:   used = saved_lo & 0x3f;
  438: 
  439:   if(used) {
  440:     unsigned long available = 64 - used;
  441: 
  442:     if(size < available) {
  443:       memcpy(&ctx->buffer[used], data, size);
  444:       return;
  445:     }
  446: 
  447:     memcpy(&ctx->buffer[used], data, available);
  448:     data = (const unsigned char *)data + available;
  449:     size -= available;
  450:     body(ctx, ctx->buffer, 64);
  451:   }
  452: 
  453:   if(size >= 64) {
  454:     data = body(ctx, data, size & ~(unsigned long)0x3f);
  455:     size &= 0x3f;
  456:   }
  457: 
  458:   memcpy(ctx->buffer, data, size);
  459: }
  460: 
  461: static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
  462: {
  463:   unsigned long used, available;
  464: 
  465:   used = ctx->lo & 0x3f;
  466: 
  467:   ctx->buffer[used++] = 0x80;
  468: 
  469:   available = 64 - used;
  470: 
  471:   if(available < 8) {
  472:     memset(&ctx->buffer[used], 0, available);
  473:     body(ctx, ctx->buffer, 64);
  474:     used = 0;
  475:     available = 64;
  476:   }
  477: 
  478:   memset(&ctx->buffer[used], 0, available - 8);
  479: 
  480:   ctx->lo <<= 3;
  481:   ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
  482:   ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
  483:   ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
  484:   ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
  485:   ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
  486:   ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
  487:   ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
  488:   ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
  489: 
  490:   body(ctx, ctx->buffer, 64);
  491: 
  492:   result[0] = curlx_ultouc((ctx->a)&0xff);
  493:   result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
  494:   result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
  495:   result[3] = curlx_ultouc(ctx->a >> 24);
  496:   result[4] = curlx_ultouc((ctx->b)&0xff);
  497:   result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
  498:   result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
  499:   result[7] = curlx_ultouc(ctx->b >> 24);
  500:   result[8] = curlx_ultouc((ctx->c)&0xff);
  501:   result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
  502:   result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
  503:   result[11] = curlx_ultouc(ctx->c >> 24);
  504:   result[12] = curlx_ultouc((ctx->d)&0xff);
  505:   result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
  506:   result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
  507:   result[15] = curlx_ultouc(ctx->d >> 24);
  508: 
  509:   memset(ctx, 0, sizeof(*ctx));
  510: }
  511: 
  512: #endif /* CRYPTO LIBS */
  513: 
  514: void Curl_md4it(unsigned char *output, const unsigned char *input,
  515:                 const size_t len)
  516: {
  517:   MD4_CTX ctx;
  518: 
  519:   MD4_Init(&ctx);
  520:   MD4_Update(&ctx, input, curlx_uztoui(len));
  521:   MD4_Final(output, &ctx);
  522: }
  523: 
  524: #endif /* CURL_DISABLE_CRYPTO_AUTH */

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