comparison src/xs_md5.c @ 4:4bb09e405eab

Added new files for 0.8
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 03 Jun 2003 11:03:04 +0000
parents
children 7048944d3bca
comparison
equal deleted inserted replaced
3:279b1e12df2b 4:4bb09e405eab
1 /*
2 Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19
20 L. Peter Deutsch
21 ghost@aladdin.com
22
23
24 Independent implementation of MD5 (RFC 1321).
25
26 This code implements the MD5 Algorithm defined in RFC 1321.
27 It is derived directly from the text of the RFC and not from the
28 reference implementation.
29
30 The original and principal author of md5.c is L. Peter Deutsch
31 <ghost@aladdin.com>. Other authors are noted in the change history
32 that follows (in reverse chronological order):
33
34 2002-08-25 ccr Edited for integration in XMMS-SID. Removed unnecessary stuff.
35 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
36 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
37 1999-05-03 lpd Original version.
38 */
39
40 #include <glib.h>
41 #include <string.h>
42 #include "xs_md5.h"
43
44 #define T1 0xd76aa478
45 #define T2 0xe8c7b756
46 #define T3 0x242070db
47 #define T4 0xc1bdceee
48 #define T5 0xf57c0faf
49 #define T6 0x4787c62a
50 #define T7 0xa8304613
51 #define T8 0xfd469501
52 #define T9 0x698098d8
53 #define T10 0x8b44f7af
54 #define T11 0xffff5bb1
55 #define T12 0x895cd7be
56 #define T13 0x6b901122
57 #define T14 0xfd987193
58 #define T15 0xa679438e
59 #define T16 0x49b40821
60 #define T17 0xf61e2562
61 #define T18 0xc040b340
62 #define T19 0x265e5a51
63 #define T20 0xe9b6c7aa
64 #define T21 0xd62f105d
65 #define T22 0x02441453
66 #define T23 0xd8a1e681
67 #define T24 0xe7d3fbc8
68 #define T25 0x21e1cde6
69 #define T26 0xc33707d6
70 #define T27 0xf4d50d87
71 #define T28 0x455a14ed
72 #define T29 0xa9e3e905
73 #define T30 0xfcefa3f8
74 #define T31 0x676f02d9
75 #define T32 0x8d2a4c8a
76 #define T33 0xfffa3942
77 #define T34 0x8771f681
78 #define T35 0x6d9d6122
79 #define T36 0xfde5380c
80 #define T37 0xa4beea44
81 #define T38 0x4bdecfa9
82 #define T39 0xf6bb4b60
83 #define T40 0xbebfbc70
84 #define T41 0x289b7ec6
85 #define T42 0xeaa127fa
86 #define T43 0xd4ef3085
87 #define T44 0x04881d05
88 #define T45 0xd9d4d039
89 #define T46 0xe6db99e5
90 #define T47 0x1fa27cf8
91 #define T48 0xc4ac5665
92 #define T49 0xf4292244
93 #define T50 0x432aff97
94 #define T51 0xab9423a7
95 #define T52 0xfc93a039
96 #define T53 0x655b59c3
97 #define T54 0x8f0ccc92
98 #define T55 0xffeff47d
99 #define T56 0x85845dd1
100 #define T57 0x6fa87e4f
101 #define T58 0xfe2ce6e0
102 #define T59 0xa3014314
103 #define T60 0x4e0811a1
104 #define T61 0xf7537e82
105 #define T62 0xbd3af235
106 #define T63 0x2ad7d2bb
107 #define T64 0xeb86d391
108
109
110 static void xs_md5_process(t_xs_md5state * pms, const guint8 * data)
111 {
112 guint32 a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2], d = pms->abcd[3];
113 guint32 t;
114 guint32 X[16];
115 const guint8 *xp = data;
116 int i;
117
118 for (i = 0; i < 16; ++i, xp += 4)
119 X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
120
121
122 /*
123 * Round 1. Let [abcd k s i] denote the operation
124 * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s).
125 */
126 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
127 #define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
128 #define SET(a, b, c, d, k, s, Ti)\
129 t = a + F(b,c,d) + X[k] + Ti;\
130 a = ROTATE_LEFT(t, s) + b
131
132 /* Do the following 16 operations. */
133 SET(a, b, c, d, 0, 7, T1);
134 SET(d, a, b, c, 1, 12, T2);
135 SET(c, d, a, b, 2, 17, T3);
136 SET(b, c, d, a, 3, 22, T4);
137 SET(a, b, c, d, 4, 7, T5);
138 SET(d, a, b, c, 5, 12, T6);
139 SET(c, d, a, b, 6, 17, T7);
140 SET(b, c, d, a, 7, 22, T8);
141 SET(a, b, c, d, 8, 7, T9);
142 SET(d, a, b, c, 9, 12, T10);
143 SET(c, d, a, b, 10, 17, T11);
144 SET(b, c, d, a, 11, 22, T12);
145 SET(a, b, c, d, 12, 7, T13);
146 SET(d, a, b, c, 13, 12, T14);
147 SET(c, d, a, b, 14, 17, T15);
148 SET(b, c, d, a, 15, 22, T16);
149
150 #undef SET
151
152 /*
153 * Round 2. Let [abcd k s i] denote the operation
154 * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s).
155 */
156 #define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
157 #define SET(a, b, c, d, k, s, Ti)\
158 t = a + G(b,c,d) + X[k] + Ti;\
159 a = ROTATE_LEFT(t, s) + b
160
161 /* Do the following 16 operations. */
162 SET(a, b, c, d, 1, 5, T17);
163 SET(d, a, b, c, 6, 9, T18);
164 SET(c, d, a, b, 11, 14, T19);
165 SET(b, c, d, a, 0, 20, T20);
166 SET(a, b, c, d, 5, 5, T21);
167 SET(d, a, b, c, 10, 9, T22);
168 SET(c, d, a, b, 15, 14, T23);
169 SET(b, c, d, a, 4, 20, T24);
170 SET(a, b, c, d, 9, 5, T25);
171 SET(d, a, b, c, 14, 9, T26);
172 SET(c, d, a, b, 3, 14, T27);
173 SET(b, c, d, a, 8, 20, T28);
174 SET(a, b, c, d, 13, 5, T29);
175 SET(d, a, b, c, 2, 9, T30);
176 SET(c, d, a, b, 7, 14, T31);
177 SET(b, c, d, a, 12, 20, T32);
178
179 #undef SET
180
181 /*
182 * Round 3. Let [abcd k s t] denote the operation
183 * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s).
184 */
185 #define H(x, y, z) ((x) ^ (y) ^ (z))
186 #define SET(a, b, c, d, k, s, Ti)\
187 t = a + H(b,c,d) + X[k] + Ti;\
188 a = ROTATE_LEFT(t, s) + b
189
190 /* Do the following 16 operations. */
191 SET(a, b, c, d, 5, 4, T33);
192 SET(d, a, b, c, 8, 11, T34);
193 SET(c, d, a, b, 11, 16, T35);
194 SET(b, c, d, a, 14, 23, T36);
195 SET(a, b, c, d, 1, 4, T37);
196 SET(d, a, b, c, 4, 11, T38);
197 SET(c, d, a, b, 7, 16, T39);
198 SET(b, c, d, a, 10, 23, T40);
199 SET(a, b, c, d, 13, 4, T41);
200 SET(d, a, b, c, 0, 11, T42);
201 SET(c, d, a, b, 3, 16, T43);
202 SET(b, c, d, a, 6, 23, T44);
203 SET(a, b, c, d, 9, 4, T45);
204 SET(d, a, b, c, 12, 11, T46);
205 SET(c, d, a, b, 15, 16, T47);
206 SET(b, c, d, a, 2, 23, T48);
207
208 #undef SET
209
210 /*
211 * Round 4. Let [abcd k s t] denote the operation
212 * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s).
213 */
214 #define I(x, y, z) ((y) ^ ((x) | ~(z)))
215 #define SET(a, b, c, d, k, s, Ti)\
216 t = a + I(b,c,d) + X[k] + Ti;\
217 a = ROTATE_LEFT(t, s) + b
218
219 /* Do the following 16 operations. */
220 SET(a, b, c, d, 0, 6, T49);
221 SET(d, a, b, c, 7, 10, T50);
222 SET(c, d, a, b, 14, 15, T51);
223 SET(b, c, d, a, 5, 21, T52);
224 SET(a, b, c, d, 12, 6, T53);
225 SET(d, a, b, c, 3, 10, T54);
226 SET(c, d, a, b, 10, 15, T55);
227 SET(b, c, d, a, 1, 21, T56);
228 SET(a, b, c, d, 8, 6, T57);
229 SET(d, a, b, c, 15, 10, T58);
230 SET(c, d, a, b, 6, 15, T59);
231 SET(b, c, d, a, 13, 21, T60);
232 SET(a, b, c, d, 4, 6, T61);
233 SET(d, a, b, c, 11, 10, T62);
234 SET(c, d, a, b, 2, 15, T63);
235 SET(b, c, d, a, 9, 21, T64);
236
237 #undef SET
238
239 /*
240 * Then perform the following additions. (That is increment each
241 * of the four registers by the value it had before this block was started.)
242 */
243 pms->abcd[0] += a;
244 pms->abcd[1] += b;
245 pms->abcd[2] += c;
246 pms->abcd[3] += d;
247 }
248
249
250 void xs_md5_init(t_xs_md5state * pms)
251 {
252 pms->count[0] = pms->count[1] = 0;
253 pms->abcd[0] = 0x67452301;
254 pms->abcd[1] = 0xefcdab89;
255 pms->abcd[2] = 0x98badcfe;
256 pms->abcd[3] = 0x10325476;
257 }
258
259
260 void xs_md5_append(t_xs_md5state * pms, const guint8 * data, int nbytes)
261 {
262 const guint8 *p = data;
263 int left = nbytes;
264 int offset = (pms->count[0] >> 3) & 63;
265 guint32 nbits = (guint32) (nbytes << 3);
266
267 if (nbytes <= 0)
268 return;
269
270 /* Update the message length. */
271 pms->count[1] += nbytes >> 29;
272 pms->count[0] += nbits;
273 if (pms->count[0] < nbits)
274 pms->count[1]++;
275
276 /* Process an initial partial block. */
277 if (offset)
278 {
279 int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
280
281 memcpy(pms->buf + offset, p, copy);
282
283 if (offset + copy < 64)
284 return;
285
286 p += copy;
287 left -= copy;
288 xs_md5_process(pms, pms->buf);
289 }
290
291 /* Process full blocks. */
292 for (; left >= 64; p += 64, left -= 64)
293 xs_md5_process(pms, p);
294
295 /* Process a final partial block. */
296 if (left)
297 memcpy(pms->buf, p, left);
298 }
299
300
301 void xs_md5_finish(t_xs_md5state * pms, t_xs_md5hash digest)
302 {
303 static const guint8 pad[64] = {
304 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
308 };
309
310 guint8 data[8];
311 gint i;
312
313 /* Save the length before padding. */
314 for (i = 0; i < 8; ++i)
315 data[i] = (guint8) (pms->count[i >> 2] >> ((i & 3) << 3));
316
317 /* Pad to 56 bytes mod 64. */
318 xs_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
319
320 /* Append the length. */
321 xs_md5_append(pms, data, 8);
322 for (i = 0; i < XS_MD5HASH_LENGTH; ++i)
323 digest[i] = (guint8) (pms->abcd[i >> 2] >> ((i & 3) << 3));
324 }
325