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