NCBI C++ ToolKit
md4.c
Go to the documentation of this file.

Go to the SVN repository for this file.

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