Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsaio/md5c.c

1/*
2 * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
3 *
4 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5 * rights reserved.
6 *
7 * License to copy and use this software is granted provided that it
8 * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9 * Algorithm" in all material mentioning or referencing this software
10 * or this function.
11 *
12 * License is also granted to make and use derivative works provided
13 * that such works are identified as "derived from the RSA Data
14 * Security, Inc. MD5 Message-Digest Algorithm" in all material
15 * mentioning or referencing the derived work.
16 *
17 * RSA Data Security, Inc. makes no representations concerning either
18 * the merchantability of this software or the suitability of this
19 * software for any particular purpose. It is provided "as is"
20 * without express or implied warranty of any kind.
21 *
22 * These notices must be retained in any copies of any part of this
23 * documentation and/or software.
24 *
25 * $Id: md5c.c,v 1.1 2005/06/24 22:47:12 curtisg Exp $
26 *
27 * This code is the same as the code published by RSA Inc. It has been
28 * edited for clarity and style only.
29 */
30
31#include <sys/types.h>
32
33#ifdef KERNEL
34#include <sys/systm.h>
35#else
36#include <string.h>
37#endif
38
39#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
40# include <Kernel/libkern/crypto/md5.h>
41#else
42# include <sys/md5.h>
43#endif
44
45
46#ifdef KERNEL
47#define memset(x,y,z)bzero(x,z);
48#define memcpy(x,y,z)bcopy(y, x, z)
49#endif
50
51#if defined(__i386__) || defined(__alpha__)
52#define Encode memcpy
53#define Decode memcpy
54#else /* __i386__ */
55static void Encode (output, input, len);
56static void Decode (output, input, len);
57static void MD5Transform (state, block);
58/*
59 * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
60 * a multiple of 4.
61 */
62
63/* XXX not prototyped, and not compatible with memcpy(). */
64static void
65Encode (output, input, len)
66unsigned char *output;
67u_int32_t *input;
68unsigned int len;
69{
70unsigned int i, j;
71
72for (i = 0, j = 0; j < len; i++, j += 4) {
73output[j] = (unsigned char)(input[i] & 0xff);
74output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
75output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
76output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
77}
78}
79
80/*
81 * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
82 * a multiple of 4.
83 */
84
85static void
86Decode (output, input, len)
87u_int32_t *output;
88const unsigned char *input;
89unsigned int len;
90{
91unsigned int i, j;
92
93for (i = 0, j = 0; j < len; i++, j += 4)
94output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
95 (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
96}
97#endif /* i386 */
98
99static unsigned char PADDING[64] = {
100 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
103};
104
105/* F, G, H and I are basic MD5 functions. */
106#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
107#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
108#define H(x, y, z) ((x) ^ (y) ^ (z))
109#define I(x, y, z) ((y) ^ ((x) | (~z)))
110
111/* ROTATE_LEFT rotates x left n bits. */
112#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
113
114/*
115 * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
116 * Rotation is separate from addition to prevent recomputation.
117 */
118#define FF(a, b, c, d, x, s, ac) { \
119(a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
120(a) = ROTATE_LEFT ((a), (s)); \
121(a) += (b); \
122}
123#define GG(a, b, c, d, x, s, ac) { \
124(a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
125(a) = ROTATE_LEFT ((a), (s)); \
126(a) += (b); \
127}
128#define HH(a, b, c, d, x, s, ac) { \
129(a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
130(a) = ROTATE_LEFT ((a), (s)); \
131(a) += (b); \
132}
133#define II(a, b, c, d, x, s, ac) { \
134(a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
135(a) = ROTATE_LEFT ((a), (s)); \
136(a) += (b); \
137}
138
139static void MD5Transform (u_int32_t state[4], const unsigned char block[64]);
140
141/* MD5 initialization. Begins an MD5 operation, writing a new context. */
142
143void
144MD5Init (context)
145MD5_CTX *context;
146{
147
148context->count[0] = context->count[1] = 0;
149
150/* Load magic initialization constants. */
151context->state[0] = 0x67452301;
152context->state[1] = 0xefcdab89;
153context->state[2] = 0x98badcfe;
154context->state[3] = 0x10325476;
155}
156
157/*
158 * MD5 block update operation. Continues an MD5 message-digest
159 * operation, processing another message block, and updating the
160 * context.
161 */
162
163void
164MD5Update (context, input, inputLen)
165MD5_CTX *context;
166#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
167const void *input;
168#else
169const unsigned char *input;
170#endif
171unsigned int inputLen;
172{
173unsigned int i, index, partLen;
174
175/* Compute number of bytes mod 64 */
176index = (unsigned int)((context->count[0] >> 3) & 0x3F);
177
178/* Update number of bits */
179if ((context->count[0] += ((u_int32_t)inputLen << 3))
180 < ((u_int32_t)inputLen << 3))
181context->count[1]++;
182context->count[1] += ((u_int32_t)inputLen >> 29);
183
184partLen = 64 - index;
185
186/* Transform as many times as possible. */
187if (inputLen >= partLen) {
188memcpy((void *)&context->buffer[index], (const void *)input,
189 partLen);
190MD5Transform (context->state, context->buffer);
191
192for (i = partLen; i + 63 < inputLen; i += 64)
193MD5Transform (context->state, &((const unsigned char *)input)[i]);
194
195index = 0;
196}
197else
198i = 0;
199
200/* Buffer remaining input */
201memcpy ((void *)&context->buffer[index], (const void *)&((const unsigned char*)input)[i],
202 inputLen-i);
203}
204
205/*
206 * MD5 padding. Adds padding followed by original length.
207 */
208
209void
210MD5Pad (context)
211MD5_CTX *context;
212{
213unsigned char bits[8];
214unsigned int index, padLen;
215
216/* Save number of bits */
217Encode (bits, context->count, 8);
218
219/* Pad out to 56 mod 64. */
220index = (unsigned int)((context->count[0] >> 3) & 0x3f);
221padLen = (index < 56) ? (56 - index) : (120 - index);
222MD5Update (context, PADDING, padLen);
223
224/* Append length (before padding) */
225MD5Update (context, bits, 8);
226}
227
228/*
229 * MD5 finalization. Ends an MD5 message-digest operation, writing the
230 * the message digest and zeroizing the context.
231 */
232
233void
234MD5Final (digest, context)
235unsigned char digest[16];
236MD5_CTX *context;
237{
238/* Do padding. */
239MD5Pad (context);
240
241/* Store state in digest */
242Encode (digest, context->state, 16);
243
244/* Zeroize sensitive information. */
245memset ((void *)context, 0, sizeof (*context));
246}
247
248/* MD5 basic transformation. Transforms state based on block. */
249
250static void
251MD5Transform (state, block)
252u_int32_t state[4];
253const unsigned char block[64];
254{
255u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
256
257Decode (x, block, 64);
258
259/* Round 1 */
260#define S11 7
261#define S12 12
262#define S13 17
263#define S14 22
264FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
265FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
266FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
267FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
268FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
269FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
270FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
271FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
272FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
273FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
274FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
275FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
276FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
277FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
278FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
279FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
280
281/* Round 2 */
282#define S21 5
283#define S22 9
284#define S23 14
285#define S24 20
286GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
287GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
288GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
289GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
290GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
291GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
292GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
293GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
294GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
295GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
296GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
297GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
298GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
299GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
300GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
301GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
302
303/* Round 3 */
304#define S31 4
305#define S32 11
306#define S33 16
307#define S34 23
308HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
309HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
310HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
311HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
312HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
313HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
314HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
315HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
316HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
317HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
318HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
319HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
320HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
321HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
322HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
323HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
324
325/* Round 4 */
326#define S41 6
327#define S42 10
328#define S43 15
329#define S44 21
330II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
331II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
332II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
333II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
334II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
335II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
336II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
337II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
338II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
339II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
340II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
341II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
342II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
343II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
344II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
345II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
346
347state[0] += a;
348state[1] += b;
349state[2] += c;
350state[3] += d;
351
352/* Zeroize sensitive information. */
353memset ((void *)x, 0, sizeof (x));
354}
355

Archive Download this file

Revision: 1601