Line data Source code
1 : /*
2 : * This code implements the MD5 message-digest algorithm.
3 : * The algorithm is due to Ron Rivest. This code was
4 : * written by Colin Plumb in 1993, no copyright is claimed.
5 : * This code is in the public domain; do with it what you wish.
6 : *
7 : * Equivalent code is available from RSA Data Security, Inc.
8 : * This code has been tested against that, and is equivalent,
9 : * except that you don't need to include two pages of legalese
10 : * with every copy.
11 : *
12 : * To compute the message digest of a chunk of bytes, declare an
13 : * MD5Context structure, pass it to MD5Init, call MD5Update as
14 : * needed on buffers full of bytes, and then call MD5Final, which
15 : * will fill a supplied 16-byte array with the digest.
16 : */
17 :
18 : /*
19 : * File from mhash library (mhash.sourceforge.net)
20 : */
21 : #include <config.h>
22 :
23 : #ifndef HAVE_NETTLE
24 :
25 : #if HAVE_STRING_H
26 : #include <string.h>
27 : #endif /* HAVE_STRING_H */
28 :
29 : #include <tds_sysdep_public.h>
30 : #include <freetds/bytes.h>
31 : #include <freetds/utils/md5.h>
32 :
33 : #ifndef WORDS_BIGENDIAN
34 : #define byteReverse(buf, len) /* Nothing */
35 : #else
36 : /*
37 : * Note: this code is harmless on little-endian machines.
38 : */
39 : static void byteReverse(uint32_t *buf, unsigned longs)
40 : {
41 : do {
42 : *buf = TDS_GET_A4LE(buf);
43 : ++buf;
44 : } while (--longs);
45 : }
46 : #endif
47 :
48 : static void MD5Transform(uint32_t buf[4], const uint32_t in[16]);
49 :
50 : /*
51 : * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
52 : * initialization constants.
53 : */
54 2158 : void MD5Init(struct MD5Context *ctx)
55 : {
56 2158 : ctx->buf[0] = 0x67452301;
57 2158 : ctx->buf[1] = 0xefcdab89;
58 2158 : ctx->buf[2] = 0x98badcfe;
59 2158 : ctx->buf[3] = 0x10325476;
60 :
61 2158 : ctx->bytes = 0;
62 2158 : }
63 :
64 : /*
65 : * Update context to reflect the concatenation of another buffer full
66 : * of bytes.
67 : */
68 4308 : void MD5Update(struct MD5Context *ctx, unsigned char const *buf, size_t len)
69 : {
70 : register uint32_t t;
71 :
72 4308 : t = ctx->bytes & 0x3f; /* Bytes already in shsInfo->data */
73 :
74 : /* Update bytecount */
75 4308 : ctx->bytes += len;
76 :
77 : /* Handle any leading odd-sized chunks */
78 :
79 4308 : if (t) {
80 12 : unsigned char *p = (unsigned char *) ctx->in + t;
81 :
82 12 : t = 64 - t;
83 12 : if (len < t) {
84 8 : memcpy(p, buf, len);
85 8 : return;
86 : }
87 4 : memcpy(p, buf, t);
88 : byteReverse(ctx->in, 16);
89 4 : MD5Transform(ctx->buf, ctx->in);
90 4 : buf += t;
91 4 : len -= t;
92 : }
93 : /* Process data in 64-byte chunks */
94 :
95 6803 : while (len >= 64) {
96 2503 : memcpy(ctx->in, buf, 64);
97 : byteReverse(ctx->in, 16);
98 2503 : MD5Transform(ctx->buf, ctx->in);
99 2503 : buf += 64;
100 2503 : len -= 64;
101 : }
102 :
103 : /* Handle any remaining bytes of data. */
104 :
105 4300 : memcpy(ctx->in, buf, len);
106 : }
107 :
108 : /*
109 : * Final wrapup - pad to 64-byte boundary with the bit pattern
110 : * 1 0* (64-bit count of bits processed, MSB-first)
111 : */
112 2158 : void MD5Final(struct MD5Context *ctx, unsigned char* digest)
113 : {
114 : unsigned int count;
115 : unsigned char *p;
116 :
117 : /* Compute number of bytes mod 64 */
118 2158 : count = ctx->bytes & 0x3F;
119 :
120 : /* Set the first char of padding to 0x80. This is safe since there is
121 : always at least one byte free */
122 2158 : p = (unsigned char *) ctx->in + count;
123 2158 : *p++ = 0x80;
124 :
125 : /* Bytes of padding needed to make 64 bytes */
126 2158 : count = 64 - 1 - count;
127 :
128 : /* Pad out to 56 mod 64 */
129 2158 : if (count < 8) {
130 : /* Two lots of padding: Pad the first block to 64 bytes */
131 4 : memset(p, 0, count);
132 : byteReverse(ctx->in, 16);
133 4 : MD5Transform(ctx->buf, ctx->in);
134 :
135 : /* Now fill the next block with 56 bytes */
136 4 : memset(ctx->in, 0, 56);
137 : } else {
138 : /* Pad block to 56 bytes */
139 2154 : memset(p, 0, count - 8);
140 : }
141 : byteReverse(ctx->in, 14);
142 :
143 : /* Append length in bits and transform */
144 2158 : ctx->in[14] = (uint32_t) (ctx->bytes << 3);
145 2158 : ctx->in[15] = (uint32_t) (ctx->bytes >> 29);
146 :
147 2158 : MD5Transform(ctx->buf, ctx->in);
148 : byteReverse(ctx->buf, 4);
149 :
150 2158 : if (digest!=NULL)
151 2158 : memcpy(digest, ctx->buf, 16);
152 2158 : memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
153 2158 : }
154 :
155 : /* The four core functions - F1 is optimized somewhat */
156 :
157 : /* #define F1(x, y, z) (x & y | ~x & z) */
158 : #define F1(x, y, z) (z ^ (x & (y ^ z)))
159 : #define F2(x, y, z) F1(z, x, y)
160 : #define F3(x, y, z) (x ^ y ^ z)
161 : #define F4(x, y, z) (y ^ (x | ~z))
162 :
163 : /* This is the central step in the MD5 algorithm. */
164 : #define MD5STEP(f, w, x, y, z, data, s) \
165 : ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
166 :
167 : /*
168 : * The core of the MD5 algorithm, this alters an existing MD5 hash to
169 : * reflect the addition of 16 longwords of new data. MD5Update blocks
170 : * the data and converts bytes into longwords for this routine.
171 : */
172 4669 : static void MD5Transform(uint32_t buf[4], const uint32_t in[16])
173 : {
174 : register uint32_t a, b, c, d;
175 :
176 4669 : a = buf[0];
177 4669 : b = buf[1];
178 4669 : c = buf[2];
179 4669 : d = buf[3];
180 :
181 4669 : MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
182 4669 : MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
183 4669 : MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
184 4669 : MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
185 4669 : MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
186 4669 : MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
187 4669 : MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
188 4669 : MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
189 4669 : MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
190 4669 : MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
191 4669 : MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
192 4669 : MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
193 4669 : MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
194 4669 : MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
195 4669 : MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
196 4669 : MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
197 :
198 4669 : MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
199 4669 : MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
200 4669 : MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
201 4669 : MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
202 4669 : MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
203 4669 : MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
204 4669 : MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
205 4669 : MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
206 4669 : MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
207 4669 : MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
208 4669 : MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
209 4669 : MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
210 4669 : MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
211 4669 : MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
212 4669 : MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
213 4669 : MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
214 :
215 4669 : MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
216 4669 : MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
217 4669 : MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
218 4669 : MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
219 4669 : MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
220 4669 : MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
221 4669 : MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
222 4669 : MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
223 4669 : MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
224 4669 : MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
225 4669 : MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
226 4669 : MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
227 4669 : MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
228 4669 : MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
229 4669 : MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
230 4669 : MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
231 :
232 4669 : MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
233 4669 : MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
234 4669 : MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
235 4669 : MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
236 4669 : MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
237 4669 : MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
238 4669 : MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
239 4669 : MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
240 4669 : MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
241 4669 : MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
242 4669 : MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
243 4669 : MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
244 4669 : MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
245 4669 : MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
246 4669 : MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
247 4669 : MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
248 :
249 4669 : buf[0] += a;
250 4669 : buf[1] += b;
251 4669 : buf[2] += c;
252 4669 : buf[3] += d;
253 4669 : }
254 :
255 : #endif
|