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 385 : MD4Init(struct MD4Context *ctx)
71 : {
72 385 : ctx->buf[0] = 0x67452301;
73 385 : ctx->buf[1] = 0xefcdab89;
74 385 : ctx->buf[2] = 0x98badcfe;
75 385 : ctx->buf[3] = 0x10325476;
76 :
77 385 : ctx->bytes = 0;
78 385 : }
79 :
80 : /*
81 : * Update context to reflect the concatenation of another buffer full
82 : * of bytes.
83 : */
84 : void
85 405 : MD4Update(struct MD4Context *ctx, unsigned char const *buf, size_t len)
86 : {
87 : register uint32_t t;
88 :
89 405 : t = ctx->bytes & 0x3f;
90 :
91 : /* Update bytecount */
92 405 : ctx->bytes += len;
93 :
94 : /* Handle any leading odd-sized chunks */
95 :
96 405 : 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 401 : 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 393 : 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 385 : 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 385 : 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 385 : p = (unsigned char *) ctx->in + count;
141 385 : *p++ = 0x80;
142 :
143 : /* Bytes of padding needed to make 64 bytes */
144 385 : count = 64 - 1 - count;
145 :
146 : /* Pad out to 56 mod 64 */
147 385 : 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 377 : memset(p, 0, count - 8);
158 : }
159 : byteReverse(ctx->in, 14);
160 :
161 : /* Append length in bits and transform */
162 385 : ctx->in[14] = (uint32_t) (ctx->bytes << 3);
163 385 : ctx->in[15] = (uint32_t) (ctx->bytes >> 29);
164 :
165 385 : MD4Transform(ctx->buf, ctx->in);
166 : byteReverse(ctx->buf, 4);
167 :
168 385 : if (digest != NULL)
169 385 : memcpy(digest, ctx->buf, 16);
170 385 : memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
171 385 : }
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 409 : MD4Transform(uint32_t buf[4], const uint32_t in[16])
198 : {
199 : register uint32_t a, b, c, d;
200 :
201 409 : a = buf[0];
202 409 : b = buf[1];
203 409 : c = buf[2];
204 409 : d = buf[3];
205 :
206 409 : FF(a, b, c, d, in[0], 3); /* 1 */
207 409 : FF(d, a, b, c, in[1], 7); /* 2 */
208 409 : FF(c, d, a, b, in[2], 11); /* 3 */
209 409 : FF(b, c, d, a, in[3], 19); /* 4 */
210 409 : FF(a, b, c, d, in[4], 3); /* 5 */
211 409 : FF(d, a, b, c, in[5], 7); /* 6 */
212 409 : FF(c, d, a, b, in[6], 11); /* 7 */
213 409 : FF(b, c, d, a, in[7], 19); /* 8 */
214 409 : FF(a, b, c, d, in[8], 3); /* 9 */
215 409 : FF(d, a, b, c, in[9], 7); /* 10 */
216 409 : FF(c, d, a, b, in[10], 11); /* 11 */
217 409 : FF(b, c, d, a, in[11], 19); /* 12 */
218 409 : FF(a, b, c, d, in[12], 3); /* 13 */
219 409 : FF(d, a, b, c, in[13], 7); /* 14 */
220 409 : FF(c, d, a, b, in[14], 11); /* 15 */
221 409 : FF(b, c, d, a, in[15], 19); /* 16 */
222 :
223 409 : GG(a, b, c, d, in[0], 3); /* 17 */
224 409 : GG(d, a, b, c, in[4], 5); /* 18 */
225 409 : GG(c, d, a, b, in[8], 9); /* 19 */
226 409 : GG(b, c, d, a, in[12], 13); /* 20 */
227 409 : GG(a, b, c, d, in[1], 3); /* 21 */
228 409 : GG(d, a, b, c, in[5], 5); /* 22 */
229 409 : GG(c, d, a, b, in[9], 9); /* 23 */
230 409 : GG(b, c, d, a, in[13], 13); /* 24 */
231 409 : GG(a, b, c, d, in[2], 3); /* 25 */
232 409 : GG(d, a, b, c, in[6], 5); /* 26 */
233 409 : GG(c, d, a, b, in[10], 9); /* 27 */
234 409 : GG(b, c, d, a, in[14], 13); /* 28 */
235 409 : GG(a, b, c, d, in[3], 3); /* 29 */
236 409 : GG(d, a, b, c, in[7], 5); /* 30 */
237 409 : GG(c, d, a, b, in[11], 9); /* 31 */
238 409 : GG(b, c, d, a, in[15], 13); /* 32 */
239 :
240 409 : HH(a, b, c, d, in[0], 3); /* 33 */
241 409 : HH(d, a, b, c, in[8], 9); /* 34 */
242 409 : HH(c, d, a, b, in[4], 11); /* 35 */
243 409 : HH(b, c, d, a, in[12], 15); /* 36 */
244 409 : HH(a, b, c, d, in[2], 3); /* 37 */
245 409 : HH(d, a, b, c, in[10], 9); /* 38 */
246 409 : HH(c, d, a, b, in[6], 11); /* 39 */
247 409 : HH(b, c, d, a, in[14], 15); /* 40 */
248 409 : HH(a, b, c, d, in[1], 3); /* 41 */
249 409 : HH(d, a, b, c, in[9], 9); /* 42 */
250 409 : HH(c, d, a, b, in[5], 11); /* 43 */
251 409 : HH(b, c, d, a, in[13], 15); /* 44 */
252 409 : HH(a, b, c, d, in[3], 3); /* 45 */
253 409 : HH(d, a, b, c, in[11], 9); /* 46 */
254 409 : HH(c, d, a, b, in[7], 11); /* 47 */
255 409 : HH(b, c, d, a, in[15], 15); /* 48 */
256 :
257 :
258 409 : buf[0] += a;
259 409 : buf[1] += b;
260 409 : buf[2] += c;
261 409 : buf[3] += d;
262 409 : }
263 :
264 : #endif
|