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
|