LCOV - code coverage report
Current view: top level - src/utils - md4.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 101 101 100.0 %
Date: 2024-04-20 12:53:58 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  *    Copyright (C) 2001 Nikos Mavroyanopoulos
       3             :  *
       4             :  *    This library is free software; you can redistribute it and/or modify it 
       5             :  *    under the terms of the GNU Library General Public License as published 
       6             :  *    by the Free Software Foundation; either version 2 of the License, or 
       7             :  *    (at your option) any later version.
       8             :  *
       9             :  *    This library is distributed in the hope that it will be useful,
      10             :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  *    Library General Public License for more details.
      13             :  *
      14             :  *    You should have received a copy of the GNU Library General Public
      15             :  *    License along with this library; if not, write to the
      16             :  *    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17             :  *    Boston, MA 02111-1307, USA.
      18             :  */
      19             : 
      20             : 
      21             : /* 
      22             :  * The algorithm is due to Ron Rivest.  This code is based on code
      23             :  * written by Colin Plumb in 1993.
      24             :  */
      25             : 
      26             : 
      27             : /*
      28             :  * This code implements the MD4 message-digest algorithm.
      29             :  */
      30             : 
      31             : /*
      32             :  * File from mhash library (mhash.sourceforge.net)
      33             :  */
      34             : #include <config.h>
      35             : 
      36             : #ifndef HAVE_NETTLE
      37             : 
      38             : #if HAVE_STRING_H
      39             : #include <string.h>
      40             : #endif /* HAVE_STRING_H */
      41             : 
      42             : #include <tds_sysdep_public.h>
      43             : #include <freetds/bytes.h>
      44             : #include <freetds/utils/md4.h>
      45             : 
      46             : #ifndef WORDS_BIGENDIAN
      47             : #define byteReverse(buf, len)   /* Nothing */
      48             : #else
      49             : /*
      50             :  * Note: this code is harmless on little-endian machines.
      51             :  */
      52             : static void
      53             : byteReverse(uint32_t *buf, unsigned longs)
      54             : {
      55             :         do {
      56             :                 *buf = TDS_GET_A4LE(buf);
      57             :                 ++buf;
      58             :         } while (--longs);
      59             : }
      60             : #endif
      61             : 
      62             : #define rotl32(x,n)   (((x) << ((uint32_t)(n))) | ((x) >> (32 - (uint32_t)(n))))
      63             : 
      64             : static void MD4Transform(uint32_t buf[4], const uint32_t in[16]);
      65             : /*
      66             :  * Start MD4 accumulation.  Set bit count to 0 and buffer to mysterious
      67             :  * initialization constants.
      68             :  */
      69             : void
      70         388 : MD4Init(struct MD4Context *ctx)
      71             : {
      72         388 :         ctx->buf[0] = 0x67452301;
      73         388 :         ctx->buf[1] = 0xefcdab89;
      74         388 :         ctx->buf[2] = 0x98badcfe;
      75         388 :         ctx->buf[3] = 0x10325476;
      76             : 
      77         388 :         ctx->bytes = 0;
      78         388 : }
      79             : 
      80             : /*
      81             :  * Update context to reflect the concatenation of another buffer full
      82             :  * of bytes.
      83             :  */
      84             : void
      85         408 : MD4Update(struct MD4Context *ctx, unsigned char const *buf, size_t len)
      86             : {
      87             :         register uint32_t t;
      88             : 
      89         408 :         t = ctx->bytes & 0x3f;
      90             : 
      91             :         /* Update bytecount */
      92         408 :         ctx->bytes += len;
      93             : 
      94             :         /* Handle any leading odd-sized chunks */
      95             : 
      96         408 :         if (t) {
      97          20 :                 unsigned char *p = (unsigned char *) ctx->in + t;
      98             : 
      99          20 :                 t = 64 - t;
     100          20 :                 if (len < t) {
     101          12 :                         memcpy(p, buf, len);
     102          12 :                         return;
     103             :                 }
     104           8 :                 memcpy(p, buf, t);
     105             :                 byteReverse(ctx->in, 16);
     106           8 :                 MD4Transform(ctx->buf, ctx->in);
     107           8 :                 buf += t;
     108           8 :                 len -= t;
     109             :         }
     110             :         /* Process data in 64-byte chunks */
     111             : 
     112         404 :         while (len >= 64) {
     113           8 :                 memcpy(ctx->in, buf, 64);
     114             :                 byteReverse(ctx->in, 16);
     115           8 :                 MD4Transform(ctx->buf, ctx->in);
     116           8 :                 buf += 64;
     117           8 :                 len -= 64;
     118             :         }
     119             : 
     120             :         /* Handle any remaining bytes of data. */
     121             : 
     122         396 :         memcpy(ctx->in, buf, len);
     123             : }
     124             : 
     125             : /*
     126             :  * Final wrapup - pad to 64-byte boundary with the bit pattern 
     127             :  * 1 0* (64-bit count of bits processed, MSB-first)
     128             :  */
     129             : void
     130         388 : MD4Final(struct MD4Context *ctx, unsigned char *digest)
     131             : {
     132             :         unsigned int count;
     133             :         unsigned char *p;
     134             : 
     135             :         /* Compute number of bytes mod 64 */
     136         388 :         count = ctx->bytes & 0x3F;
     137             : 
     138             :         /* Set the first char of padding to 0x80.  This is safe since there is
     139             :          * always at least one byte free */
     140         388 :         p = (unsigned char *) ctx->in + count;
     141         388 :         *p++ = 0x80;
     142             : 
     143             :         /* Bytes of padding needed to make 64 bytes */
     144         388 :         count = 64 - 1 - count;
     145             : 
     146             :         /* Pad out to 56 mod 64 */
     147         388 :         if (count < 8) {
     148             :                 /* Two lots of padding:  Pad the first block to 64 bytes */
     149           8 :                 memset(p, 0, count);
     150             :                 byteReverse(ctx->in, 16);
     151           8 :                 MD4Transform(ctx->buf, ctx->in);
     152             : 
     153             :                 /* Now fill the next block with 56 bytes */
     154           8 :                 memset(ctx->in, 0, 56);
     155             :         } else {
     156             :                 /* Pad block to 56 bytes */
     157         380 :                 memset(p, 0, count - 8);
     158             :         }
     159             :         byteReverse(ctx->in, 14);
     160             : 
     161             :         /* Append length in bits and transform */
     162         388 :         ctx->in[14] = (uint32_t) (ctx->bytes << 3);
     163         388 :         ctx->in[15] = (uint32_t) (ctx->bytes >> 29);
     164             : 
     165         388 :         MD4Transform(ctx->buf, ctx->in);
     166             :         byteReverse(ctx->buf, 4);
     167             : 
     168         388 :         if (digest != NULL)
     169         388 :                 memcpy(digest, ctx->buf, 16);
     170         388 :         memset(ctx, 0, sizeof(*ctx));   /* In case it's sensitive */
     171         388 : }
     172             : 
     173             : /* The three core functions */
     174             : 
     175             : #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
     176             : #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
     177             : #define H(x, y, z) ((x) ^ (y) ^ (z))
     178             : 
     179             : #define FF(a, b, c, d, x, s) { \
     180             :     (a) += F ((b), (c), (d)) + (x); \
     181             :     (a) = rotl32 ((a), (s)); \
     182             :   }
     183             : #define GG(a, b, c, d, x, s) { \
     184             :     (a) += G ((b), (c), (d)) + (x) + (uint32_t)0x5a827999; \
     185             :     (a) = rotl32 ((a), (s)); \
     186             :   }
     187             : #define HH(a, b, c, d, x, s) { \
     188             :     (a) += H ((b), (c), (d)) + (x) + (uint32_t)0x6ed9eba1; \
     189             :     (a) = rotl32 ((a), (s)); \
     190             :   }
     191             : 
     192             : 
     193             : /*
     194             :  * The core of the MD4 algorithm
     195             :  */
     196             : static void
     197         412 : MD4Transform(uint32_t buf[4], const uint32_t in[16])
     198             : {
     199             :         register uint32_t a, b, c, d;
     200             : 
     201         412 :         a = buf[0];
     202         412 :         b = buf[1];
     203         412 :         c = buf[2];
     204         412 :         d = buf[3];
     205             : 
     206         412 :         FF(a, b, c, d, in[0], 3);       /* 1 */
     207         412 :         FF(d, a, b, c, in[1], 7);       /* 2 */
     208         412 :         FF(c, d, a, b, in[2], 11);      /* 3 */
     209         412 :         FF(b, c, d, a, in[3], 19);      /* 4 */
     210         412 :         FF(a, b, c, d, in[4], 3);       /* 5 */
     211         412 :         FF(d, a, b, c, in[5], 7);       /* 6 */
     212         412 :         FF(c, d, a, b, in[6], 11);      /* 7 */
     213         412 :         FF(b, c, d, a, in[7], 19);      /* 8 */
     214         412 :         FF(a, b, c, d, in[8], 3);       /* 9 */
     215         412 :         FF(d, a, b, c, in[9], 7);       /* 10 */
     216         412 :         FF(c, d, a, b, in[10], 11);     /* 11 */
     217         412 :         FF(b, c, d, a, in[11], 19);     /* 12 */
     218         412 :         FF(a, b, c, d, in[12], 3);      /* 13 */
     219         412 :         FF(d, a, b, c, in[13], 7);      /* 14 */
     220         412 :         FF(c, d, a, b, in[14], 11);     /* 15 */
     221         412 :         FF(b, c, d, a, in[15], 19);     /* 16 */
     222             : 
     223         412 :         GG(a, b, c, d, in[0], 3);       /* 17 */
     224         412 :         GG(d, a, b, c, in[4], 5);       /* 18 */
     225         412 :         GG(c, d, a, b, in[8], 9);       /* 19 */
     226         412 :         GG(b, c, d, a, in[12], 13);     /* 20 */
     227         412 :         GG(a, b, c, d, in[1], 3);       /* 21 */
     228         412 :         GG(d, a, b, c, in[5], 5);       /* 22 */
     229         412 :         GG(c, d, a, b, in[9], 9);       /* 23 */
     230         412 :         GG(b, c, d, a, in[13], 13);     /* 24 */
     231         412 :         GG(a, b, c, d, in[2], 3);       /* 25 */
     232         412 :         GG(d, a, b, c, in[6], 5);       /* 26 */
     233         412 :         GG(c, d, a, b, in[10], 9);      /* 27 */
     234         412 :         GG(b, c, d, a, in[14], 13);     /* 28 */
     235         412 :         GG(a, b, c, d, in[3], 3);       /* 29 */
     236         412 :         GG(d, a, b, c, in[7], 5);       /* 30 */
     237         412 :         GG(c, d, a, b, in[11], 9);      /* 31 */
     238         412 :         GG(b, c, d, a, in[15], 13);     /* 32 */
     239             : 
     240         412 :         HH(a, b, c, d, in[0], 3);       /* 33 */
     241         412 :         HH(d, a, b, c, in[8], 9);       /* 34 */
     242         412 :         HH(c, d, a, b, in[4], 11);      /* 35 */
     243         412 :         HH(b, c, d, a, in[12], 15);     /* 36 */
     244         412 :         HH(a, b, c, d, in[2], 3);       /* 37 */
     245         412 :         HH(d, a, b, c, in[10], 9);      /* 38 */
     246         412 :         HH(c, d, a, b, in[6], 11);      /* 39 */
     247         412 :         HH(b, c, d, a, in[14], 15);     /* 40 */
     248         412 :         HH(a, b, c, d, in[1], 3);       /* 41 */
     249         412 :         HH(d, a, b, c, in[9], 9);       /* 42 */
     250         412 :         HH(c, d, a, b, in[5], 11);      /* 43 */
     251         412 :         HH(b, c, d, a, in[13], 15);     /* 44 */
     252         412 :         HH(a, b, c, d, in[3], 3);       /* 45 */
     253         412 :         HH(d, a, b, c, in[11], 9);      /* 46 */
     254         412 :         HH(c, d, a, b, in[7], 11);      /* 47 */
     255         412 :         HH(b, c, d, a, in[15], 15);     /* 48 */
     256             : 
     257             : 
     258         412 :         buf[0] += a;
     259         412 :         buf[1] += b;
     260         412 :         buf[2] += c;
     261         412 :         buf[3] += d;
     262         412 : }
     263             : 
     264             : #endif

Generated by: LCOV version 1.13