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 : /* This code was modified in 1997 by Jim Kingdon of Cyclic Software to
19 : not require an integer type which is exactly 32 bits. This work
20 : draws on the changes for the same purpose by Tatu Ylonen
21 : <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
22 : that code, there is no copyright issue. I hereby disclaim
23 : copyright in any changes I have made; this code remains in the
24 : public domain. */
25 :
26 : /* Note regarding cvs_* namespace: this avoids potential conflicts
27 : with libraries such as some versions of Kerberos. No particular
28 : need to worry about whether the system supplies an MD5 library, as
29 : this file is only about 3k of object code. */
30 :
31 : /* Modified by E. Rouault, to fix :
32 : warning: argument to 'sizeof' in 'memset' call is the same expression as the destination; did you mean to dereference it? [-Wsizeof-pointer-memaccess]
33 : memset(ctx, 0, sizeof(ctx)); */ /* In case it's sensitive */
34 : /* at the end of cvs_MD5Final */
35 :
36 : #ifdef HAVE_CONFIG_H
37 : #include "config.h"
38 : #endif
39 :
40 : #include <string.h> /* for memcpy() and memset() */
41 :
42 : #include "md5.h"
43 :
44 : /* Little-endian byte-swapping routines. Note that these do not
45 : depend on the size of datatypes such as cvs_uint32, nor do they require
46 : us to detect the endianness of the machine we are running on. It
47 : is possible they should be macros for speed, but I would be
48 : surprised if they were a performance bottleneck for MD5. */
49 :
50 0 : static cvs_uint32 getu32(const unsigned char *addr)
51 : {
52 0 : return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
53 0 : | addr[1]) << 8 | addr[0];
54 : }
55 :
56 : static void
57 0 : putu32 (
58 : cvs_uint32 data,
59 : unsigned char *addr)
60 : {
61 0 : addr[0] = (unsigned char)data;
62 0 : addr[1] = (unsigned char)(data >> 8);
63 0 : addr[2] = (unsigned char)(data >> 16);
64 0 : addr[3] = (unsigned char)(data >> 24);
65 0 : }
66 :
67 : /*
68 : * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
69 : * initialization constants.
70 : */
71 : void
72 0 : cvs_MD5Init (
73 : struct cvs_MD5Context *ctx)
74 : {
75 0 : ctx->buf[0] = 0x67452301;
76 0 : ctx->buf[1] = 0xefcdab89;
77 0 : ctx->buf[2] = 0x98badcfe;
78 0 : ctx->buf[3] = 0x10325476;
79 :
80 0 : ctx->bits[0] = 0;
81 0 : ctx->bits[1] = 0;
82 0 : }
83 :
84 : /*
85 : * Update context to reflect the concatenation of another buffer full
86 : * of bytes.
87 : */
88 : void
89 0 : cvs_MD5Update (
90 : struct cvs_MD5Context *ctx,
91 : unsigned char const *buf,
92 : unsigned len)
93 : {
94 : cvs_uint32 t;
95 :
96 : /* Update bitcount */
97 :
98 0 : t = ctx->bits[0];
99 0 : if ((ctx->bits[0] = (t + ((cvs_uint32)len << 3)) & 0xffffffff) < t)
100 0 : ctx->bits[1]++; /* Carry from low to high */
101 0 : ctx->bits[1] += len >> 29;
102 :
103 0 : t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
104 :
105 : /* Handle any leading odd-sized chunks */
106 :
107 0 : if ( t ) {
108 0 : unsigned char *p = ctx->in + t;
109 :
110 0 : t = 64-t;
111 0 : if (len < t) {
112 0 : memcpy(p, buf, len);
113 0 : return;
114 : }
115 0 : memcpy(p, buf, t);
116 0 : cvs_MD5Transform (ctx->buf, ctx->in);
117 0 : buf += t;
118 0 : len -= t;
119 : }
120 :
121 : /* Process data in 64-byte chunks */
122 :
123 0 : while (len >= 64) {
124 0 : memcpy(ctx->in, buf, 64);
125 0 : cvs_MD5Transform (ctx->buf, ctx->in);
126 0 : buf += 64;
127 0 : len -= 64;
128 : }
129 :
130 : /* Handle any remaining bytes of data. */
131 :
132 0 : memcpy(ctx->in, buf, len);
133 : }
134 :
135 : /*
136 : * Final wrapup - pad to 64-byte boundary with the bit pattern
137 : * 1 0* (64-bit count of bits processed, MSB-first)
138 : */
139 : void
140 0 : cvs_MD5Final (
141 : unsigned char digest[16],
142 : struct cvs_MD5Context *ctx)
143 : {
144 : unsigned count;
145 : unsigned char *p;
146 :
147 : /* Compute number of bytes mod 64 */
148 0 : count = (ctx->bits[0] >> 3) & 0x3F;
149 :
150 : /* Set the first char of padding to 0x80. This is safe since there is
151 : always at least one byte free */
152 0 : p = ctx->in + count;
153 0 : *p++ = 0x80;
154 :
155 : /* Bytes of padding needed to make 64 bytes */
156 0 : count = 64 - 1 - count;
157 :
158 : /* Pad out to 56 mod 64 */
159 0 : if (count < 8) {
160 : /* Two lots of padding: Pad the first block to 64 bytes */
161 0 : memset(p, 0, count);
162 0 : cvs_MD5Transform (ctx->buf, ctx->in);
163 :
164 : /* Now fill the next block with 56 bytes */
165 0 : memset(ctx->in, 0, 56);
166 : } else {
167 : /* Pad block to 56 bytes */
168 0 : memset(p, 0, count-8);
169 : }
170 :
171 : /* Append length in bits and transform */
172 0 : putu32(ctx->bits[0], ctx->in + 56);
173 0 : putu32(ctx->bits[1], ctx->in + 60);
174 :
175 0 : cvs_MD5Transform (ctx->buf, ctx->in);
176 0 : putu32(ctx->buf[0], digest);
177 0 : putu32(ctx->buf[1], digest + 4);
178 0 : putu32(ctx->buf[2], digest + 8);
179 0 : putu32(ctx->buf[3], digest + 12);
180 0 : memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
181 0 : }
182 :
183 : #ifndef ASM_MD5
184 :
185 : /* The four core functions - F1 is optimized somewhat */
186 :
187 : /* #define F1(x, y, z) (x & y | ~x & z) */
188 : #define F1(x, y, z) (z ^ (x & (y ^ z)))
189 : #define F2(x, y, z) F1(z, x, y)
190 : #define F3(x, y, z) (x ^ y ^ z)
191 : #define F4(x, y, z) (y ^ (x | ~z))
192 :
193 : /* This is the central step in the MD5 algorithm. */
194 : #define MD5STEP(f, w, x, y, z, data, s) \
195 : ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
196 :
197 : /*
198 : * The core of the MD5 algorithm, this alters an existing MD5 hash to
199 : * reflect the addition of 16 longwords of new data. MD5Update blocks
200 : * the data and converts bytes into longwords for this routine.
201 : */
202 : void
203 0 : cvs_MD5Transform (
204 : cvs_uint32 buf[4],
205 : const unsigned char inraw[64])
206 : {
207 : register cvs_uint32 a, b, c, d;
208 : cvs_uint32 in[16];
209 : int i;
210 :
211 0 : for (i = 0; i < 16; ++i)
212 0 : in[i] = getu32 (inraw + 4 * i);
213 :
214 0 : a = buf[0];
215 0 : b = buf[1];
216 0 : c = buf[2];
217 0 : d = buf[3];
218 :
219 0 : MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
220 0 : MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
221 0 : MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
222 0 : MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
223 0 : MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
224 0 : MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
225 0 : MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
226 0 : MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
227 0 : MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
228 0 : MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
229 0 : MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
230 0 : MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
231 0 : MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
232 0 : MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
233 0 : MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
234 0 : MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
235 :
236 0 : MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
237 0 : MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
238 0 : MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
239 0 : MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
240 0 : MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
241 0 : MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
242 0 : MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
243 0 : MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
244 0 : MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
245 0 : MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
246 0 : MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
247 0 : MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
248 0 : MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
249 0 : MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
250 0 : MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
251 0 : MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
252 :
253 0 : MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
254 0 : MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
255 0 : MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
256 0 : MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
257 0 : MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
258 0 : MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
259 0 : MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
260 0 : MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
261 0 : MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
262 0 : MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
263 0 : MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
264 0 : MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
265 0 : MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
266 0 : MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
267 0 : MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
268 0 : MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
269 :
270 0 : MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
271 0 : MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
272 0 : MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
273 0 : MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
274 0 : MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
275 0 : MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
276 0 : MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
277 0 : MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
278 0 : MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
279 0 : MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
280 0 : MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
281 0 : MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
282 0 : MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
283 0 : MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
284 0 : MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
285 0 : MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
286 :
287 0 : buf[0] += a;
288 0 : buf[1] += b;
289 0 : buf[2] += c;
290 0 : buf[3] += d;
291 0 : }
292 : #endif
|