Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/libmd5/md5.c

Source at commit 1406 created 12 years 10 months ago.
By meklort, Revert drivers.c so that kexts are only loaded when OSBundleRequired is set and that value is not safe mode. Added some comments about it too.
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 * Changed so as no longer to depend on Colin Plumb's `usual.h' header
18 * definitions; now uses stuff from dpkg's config.h.
19 * - Ian Jackson <ian@chiark.greenend.org.uk>.
20 * Still in the public domain.
21 */
22
23#include <string.h>/* for memcpy() */
24#include <sys/types.h>/* for stupid systems */
25
26#include "md5.h"
27
28void
29MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
30
31int g_bigEndian = 0;
32int g_endianessDetected = 0;
33
34static void
35detectEndianess()
36{
37 int nl = 0x12345678;
38 short ns = 0x1234;
39
40 unsigned char *p = (unsigned char *)(&nl);
41 unsigned char *sp = (unsigned char *)(&ns);
42
43 if (g_endianessDetected) return;
44 if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
45 {
46 g_bigEndian = 1;
47 }
48 else if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
49 {
50 g_bigEndian = 0;
51 }
52 else
53 {
54 g_bigEndian = *sp != 0x12;
55 }
56
57 g_endianessDetected=1;
58}
59
60static void
61byteSwap(UWORD32 *buf, unsigned words)
62{
63 md5byte *p;
64
65 if (!g_bigEndian) return;
66
67p = (md5byte *)buf;
68
69do {
70*buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
71((unsigned)p[1] << 8 | p[0]);
72p += 4;
73} while (--words);
74}
75
76/*
77 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
78 * initialization constants.
79 */
80void
81MD5Init(struct MD5Context *ctx)
82{
83 detectEndianess();
84
85ctx->buf[0] = 0x67452301;
86ctx->buf[1] = 0xefcdab89;
87ctx->buf[2] = 0x98badcfe;
88ctx->buf[3] = 0x10325476;
89
90ctx->bytes[0] = 0;
91ctx->bytes[1] = 0;
92}
93
94/*
95 * Update context to reflect the concatenation of another buffer full
96 * of bytes.
97 */
98void
99MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
100{
101UWORD32 t;
102
103/* Update byte count */
104
105t = ctx->bytes[0];
106if ((ctx->bytes[0] = t + len) < t)
107ctx->bytes[1]++;/* Carry from low to high */
108
109t = 64 - (t & 0x3f);/* Space available in ctx->in (at least 1) */
110if (t > len) {
111memcpy((md5byte *)ctx->in + 64 - t, buf, len);
112return;
113}
114/* First chunk is an odd size */
115memcpy((md5byte *)ctx->in + 64 - t, buf, t);
116byteSwap(ctx->in, 16);
117MD5Transform(ctx->buf, ctx->in);
118buf += t;
119len -= t;
120
121/* Process data in 64-byte chunks */
122while (len >= 64) {
123memcpy(ctx->in, buf, 64);
124byteSwap(ctx->in, 16);
125MD5Transform(ctx->buf, ctx->in);
126buf += 64;
127len -= 64;
128}
129
130/* Handle any remaining bytes of data. */
131memcpy(ctx->in, buf, len);
132}
133
134/*
135 * Final wrapup - pad to 64-byte boundary with the bit pattern
136 * 1 0* (64-bit count of bits processed, MSB-first)
137 */
138void
139MD5Final(md5byte digest[16], struct MD5Context *ctx)
140{
141int count = ctx->bytes[0] & 0x3f;/* Number of bytes in ctx->in */
142md5byte *p = (md5byte *)ctx->in + count;
143
144/* Set the first char of padding to 0x80. There is always room. */
145*p++ = 0x80;
146
147/* Bytes of padding needed to make 56 bytes (-8..55) */
148count = 56 - 1 - count;
149
150if (count < 0) {/* Padding forces an extra block */
151memset(p, 0, count + 8);
152byteSwap(ctx->in, 16);
153MD5Transform(ctx->buf, ctx->in);
154p = (md5byte *)ctx->in;
155count = 56;
156}
157memset(p, 0, count);
158byteSwap(ctx->in, 14);
159
160/* Append length in bits and transform */
161ctx->in[14] = ctx->bytes[0] << 3;
162ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
163MD5Transform(ctx->buf, ctx->in);
164
165byteSwap(ctx->buf, 4);
166memcpy(digest, ctx->buf, 16);
167memset(ctx, 0, sizeof(ctx));/* In case it's sensitive */
168}
169
170#ifndef ASM_MD5
171
172/* The four core functions - F1 is optimized somewhat */
173
174/* #define F1(x, y, z) (x & y | ~x & z) */
175#define F1(x, y, z) (z ^ (x & (y ^ z)))
176#define F2(x, y, z) F1(z, x, y)
177#define F3(x, y, z) (x ^ y ^ z)
178#define F4(x, y, z) (y ^ (x | ~z))
179
180/* This is the central step in the MD5 algorithm. */
181#define MD5STEP(f,w,x,y,z,in,s) \
182 (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
183
184/*
185 * The core of the MD5 algorithm, this alters an existing MD5 hash to
186 * reflect the addition of 16 longwords of new data. MD5Update blocks
187 * the data and converts bytes into longwords for this routine.
188 */
189void
190MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
191{
192register UWORD32 a, b, c, d;
193
194a = buf[0];
195b = buf[1];
196c = buf[2];
197d = buf[3];
198
199MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
200MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
201MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
202MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
203MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
204MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
205MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
206MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
207MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
208MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
209MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
210MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
211MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
212MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
213MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
214MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
215
216MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
217MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
218MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
219MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
220MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
221MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
222MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
223MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
224MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
225MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
226MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
227MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
228MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
229MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
230MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
231MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
232
233MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
234MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
235MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
236MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
237MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
238MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
239MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
240MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
241MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
242MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
243MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
244MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
245MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
246MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
247MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
248MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
249
250MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
251MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
252MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
253MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
254MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
255MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
256MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
257MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
258MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
259MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
260MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
261MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
262MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
263MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
264MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
265MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
266
267buf[0] += a;
268buf[1] += b;
269buf[2] += c;
270buf[3] += d;
271}
272
273#endif
274
275void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16])
276{
277 struct MD5Context md5;
278 MD5Init(&md5);
279 MD5Update(&md5,buf,len);
280 MD5Final(sig,&md5);
281}
282
283#define HEX_STRING "0123456789abcdef" /* to convert to hex */
284
285void MD5SigToString(unsigned char signature[16],char *str,int len)
286{
287 unsigned char *sig_p;
288 char *str_p, *max_p;
289 unsigned int high, low;
290
291 str_p = str;
292 max_p = str + len;
293
294 for (sig_p = (unsigned char *)signature;
295 sig_p < (unsigned char *)signature + 16;
296 sig_p++)
297 {
298 high = *sig_p / 16;
299 low = *sig_p % 16;
300 /* account for 2 chars */
301 if (str_p + 1 >= max_p) {
302 break;
303 }
304 *str_p++ = HEX_STRING[high];
305 *str_p++ = HEX_STRING[low];
306 }
307 /* account for 2 chars */
308 if (str_p < max_p) {
309 *str_p++ = '\0';
310 }
311}
312
313
314

Archive Download this file

Revision: 1406