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: 2026-11-07 23:58:45 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             : /*
      67             :  * Start MD4 accumulation.  Set bit count to 0 and buffer to mysterious
      68             :  * initialization constants.
      69             :  */
      70             : void
      71         428 : MD4Init(struct MD4Context *ctx)
      72             : {
      73         428 :         ctx->buf[0] = 0x67452301;
      74         428 :         ctx->buf[1] = 0xefcdab89;
      75         428 :         ctx->buf[2] = 0x98badcfe;
      76         428 :         ctx->buf[3] = 0x10325476;
      77             : 
      78         428 :         ctx->bytes = 0;
      79         428 : }
      80             : 
      81             : /*
      82             :  * Update context to reflect the concatenation of another buffer full
      83             :  * of bytes.
      84             :  */
      85             : void
      86         453 : MD4Update(struct MD4Context *ctx, unsigned char const *buf, size_t len)
      87             : {
      88             :         register uint32_t t;
      89             : 
      90         453 :         t = ctx->bytes & 0x3f;
      91             : 
      92             :         /* Update bytecount */
      93         453 :         ctx->bytes += len;
      94             : 
      95             :         /* Handle any leading odd-sized chunks */
      96             : 
      97         453 :         if (t) {
      98          25 :                 unsigned char *p = (unsigned char *) ctx->in + t;
      99             : 
     100          25 :                 t = 64 - t;
     101          25 :                 if (len < t) {
     102          15 :                         memcpy(p, buf, len);
     103          15 :                         return;
     104             :                 }
     105          10 :                 memcpy(p, buf, t);
     106             :                 byteReverse(ctx->in, 16);
     107          10 :                 MD4Transform(ctx->buf, ctx->in);
     108          10 :                 buf += t;
     109          10 :                 len -= t;
     110             :         }
     111             :         /* Process data in 64-byte chunks */
     112             : 
     113         448 :         while (len >= 64) {
     114          10 :                 memcpy(ctx->in, buf, 64);
     115             :                 byteReverse(ctx->in, 16);
     116          10 :                 MD4Transform(ctx->buf, ctx->in);
     117          10 :                 buf += 64;
     118          10 :                 len -= 64;
     119             :         }
     120             : 
     121             :         /* Handle any remaining bytes of data. */
     122             : 
     123         438 :         memcpy(ctx->in, buf, len);
     124             : }
     125             : 
     126             : /*
     127             :  * Final wrapup - pad to 64-byte boundary with the bit pattern 
     128             :  * 1 0* (64-bit count of bits processed, MSB-first)
     129             :  */
     130             : void
     131         428 : MD4Final(struct MD4Context *ctx, unsigned char *digest)
     132             : {
     133             :         unsigned int count;
     134             :         unsigned char *p;
     135             : 
     136             :         /* Compute number of bytes mod 64 */
     137         428 :         count = ctx->bytes & 0x3F;
     138             : 
     139             :         /* Set the first char of padding to 0x80.  This is safe since there is
     140             :          * always at least one byte free */
     141         428 :         p = (unsigned char *) ctx->in + count;
     142         428 :         *p++ = 0x80;
     143             : 
     144             :         /* Bytes of padding needed to make 64 bytes */
     145         428 :         count = 64 - 1 - count;
     146             : 
     147             :         /* Pad out to 56 mod 64 */
     148         428 :         if (count < 8) {
     149             :                 /* Two lots of padding:  Pad the first block to 64 bytes */
     150          10 :                 memset(p, 0, count);
     151             :                 byteReverse(ctx->in, 16);
     152          10 :                 MD4Transform(ctx->buf, ctx->in);
     153             : 
     154             :                 /* Now fill the next block with 56 bytes */
     155          10 :                 memset(ctx->in, 0, 56);
     156             :         } else {
     157             :                 /* Pad block to 56 bytes */
     158         418 :                 memset(p, 0, count - 8);
     159             :         }
     160             :         byteReverse(ctx->in, 14);
     161             : 
     162             :         /* Append length in bits and transform */
     163         428 :         ctx->in[14] = (uint32_t) (ctx->bytes << 3);
     164         428 :         ctx->in[15] = (uint32_t) (ctx->bytes >> 29);
     165             : 
     166         428 :         MD4Transform(ctx->buf, ctx->in);
     167             :         byteReverse(ctx->buf, 4);
     168             : 
     169         428 :         if (digest != NULL)
     170         428 :                 memcpy(digest, ctx->buf, 16);
     171         428 :         memset(ctx, 0, sizeof(*ctx));   /* In case it's sensitive */
     172         428 : }
     173             : 
     174             : /* The three core functions */
     175             : 
     176             : #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
     177             : #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
     178             : #define H(x, y, z) ((x) ^ (y) ^ (z))
     179             : 
     180             : #define FF(a, b, c, d, x, s) { \
     181             :     (a) += F ((b), (c), (d)) + (x); \
     182             :     (a) = rotl32 ((a), (s)); \
     183             :   }
     184             : #define GG(a, b, c, d, x, s) { \
     185             :     (a) += G ((b), (c), (d)) + (x) + (uint32_t)0x5a827999; \
     186             :     (a) = rotl32 ((a), (s)); \
     187             :   }
     188             : #define HH(a, b, c, d, x, s) { \
     189             :     (a) += H ((b), (c), (d)) + (x) + (uint32_t)0x6ed9eba1; \
     190             :     (a) = rotl32 ((a), (s)); \
     191             :   }
     192             : 
     193             : 
     194             : /*
     195             :  * The core of the MD4 algorithm
     196             :  */
     197             : static void
     198         458 : MD4Transform(uint32_t buf[4], const uint32_t in[16])
     199             : {
     200             :         register uint32_t a, b, c, d;
     201             : 
     202         458 :         a = buf[0];
     203         458 :         b = buf[1];
     204         458 :         c = buf[2];
     205         458 :         d = buf[3];
     206             : 
     207         458 :         FF(a, b, c, d, in[0], 3);       /* 1 */
     208         458 :         FF(d, a, b, c, in[1], 7);       /* 2 */
     209         458 :         FF(c, d, a, b, in[2], 11);      /* 3 */
     210         458 :         FF(b, c, d, a, in[3], 19);      /* 4 */
     211         458 :         FF(a, b, c, d, in[4], 3);       /* 5 */
     212         458 :         FF(d, a, b, c, in[5], 7);       /* 6 */
     213         458 :         FF(c, d, a, b, in[6], 11);      /* 7 */
     214         458 :         FF(b, c, d, a, in[7], 19);      /* 8 */
     215         458 :         FF(a, b, c, d, in[8], 3);       /* 9 */
     216         458 :         FF(d, a, b, c, in[9], 7);       /* 10 */
     217         458 :         FF(c, d, a, b, in[10], 11);     /* 11 */
     218         458 :         FF(b, c, d, a, in[11], 19);     /* 12 */
     219         458 :         FF(a, b, c, d, in[12], 3);      /* 13 */
     220         458 :         FF(d, a, b, c, in[13], 7);      /* 14 */
     221         458 :         FF(c, d, a, b, in[14], 11);     /* 15 */
     222         458 :         FF(b, c, d, a, in[15], 19);     /* 16 */
     223             : 
     224         458 :         GG(a, b, c, d, in[0], 3);       /* 17 */
     225         458 :         GG(d, a, b, c, in[4], 5);       /* 18 */
     226         458 :         GG(c, d, a, b, in[8], 9);       /* 19 */
     227         458 :         GG(b, c, d, a, in[12], 13);     /* 20 */
     228         458 :         GG(a, b, c, d, in[1], 3);       /* 21 */
     229         458 :         GG(d, a, b, c, in[5], 5);       /* 22 */
     230         458 :         GG(c, d, a, b, in[9], 9);       /* 23 */
     231         458 :         GG(b, c, d, a, in[13], 13);     /* 24 */
     232         458 :         GG(a, b, c, d, in[2], 3);       /* 25 */
     233         458 :         GG(d, a, b, c, in[6], 5);       /* 26 */
     234         458 :         GG(c, d, a, b, in[10], 9);      /* 27 */
     235         458 :         GG(b, c, d, a, in[14], 13);     /* 28 */
     236         458 :         GG(a, b, c, d, in[3], 3);       /* 29 */
     237         458 :         GG(d, a, b, c, in[7], 5);       /* 30 */
     238         458 :         GG(c, d, a, b, in[11], 9);      /* 31 */
     239         458 :         GG(b, c, d, a, in[15], 13);     /* 32 */
     240             : 
     241         458 :         HH(a, b, c, d, in[0], 3);       /* 33 */
     242         458 :         HH(d, a, b, c, in[8], 9);       /* 34 */
     243         458 :         HH(c, d, a, b, in[4], 11);      /* 35 */
     244         458 :         HH(b, c, d, a, in[12], 15);     /* 36 */
     245         458 :         HH(a, b, c, d, in[2], 3);       /* 37 */
     246         458 :         HH(d, a, b, c, in[10], 9);      /* 38 */
     247         458 :         HH(c, d, a, b, in[6], 11);      /* 39 */
     248         458 :         HH(b, c, d, a, in[14], 15);     /* 40 */
     249         458 :         HH(a, b, c, d, in[1], 3);       /* 41 */
     250         458 :         HH(d, a, b, c, in[9], 9);       /* 42 */
     251         458 :         HH(c, d, a, b, in[5], 11);      /* 43 */
     252         458 :         HH(b, c, d, a, in[13], 15);     /* 44 */
     253         458 :         HH(a, b, c, d, in[3], 3);       /* 45 */
     254         458 :         HH(d, a, b, c, in[11], 9);      /* 46 */
     255         458 :         HH(c, d, a, b, in[7], 11);      /* 47 */
     256         458 :         HH(b, c, d, a, in[15], 15);     /* 48 */
     257             : 
     258             : 
     259         458 :         buf[0] += a;
     260         458 :         buf[1] += b;
     261         458 :         buf[2] += c;
     262         458 :         buf[3] += d;
     263         458 : }
     264             : 
     265             : #endif

Generated by: LCOV version 1.13