"Fossies" - the Fresh Open Source Software Archive 
Member "zsync-0.6.2/librcksum/md4.c" (16 Sep 2010, 7321 Bytes) of package /linux/privat/old/zsync-0.6.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "md4.c" see the
Fossies "Dox" file reference documentation.
1 /* $OpenBSD: md4.c,v 1.6 2004/05/28 15:10:27 millert Exp $ */
2
3 /*
4 * This code implements the MD4 message-digest algorithm.
5 * The algorithm is due to Ron Rivest. This code was
6 * written by Colin Plumb in 1993, no copyright is claimed.
7 * This code is in the public domain; do with it what you wish.
8 * Todd C. Miller modified the MD5 code to do MD4 based on RFC 1186.
9 *
10 * Equivalent code is available from RSA Data Security, Inc.
11 * This code has been tested against that, and is equivalent,
12 * except that you don't need to include two pages of legalese
13 * with every copy.
14 *
15 * To compute the message digest of a chunk of bytes, declare an
16 * MD4Context structure, pass it to MD4Init, call MD4Update as
17 * needed on buffers full of bytes, and then call MD4Final, which
18 * will fill a supplied 16-byte array with the digest.
19 */
20
21 #if defined(LIBC_SCCS) && !defined(lint)
22 static const char rcsid[] = "$OpenBSD: md4.c,v 1.6 2004/05/28 15:10:27 millert Exp $";
23 #endif /* LIBC_SCCS and not lint */
24
25 #include <sys/types.h>
26 #include <string.h>
27 #include "md4.h"
28
29 /* Map Solaris endian stuff to something useful */
30 #if defined(_BIG_ENDIAN) && !defined(_BYTE_ORDER)
31 #define LITTLE_ENDIAN 0
32 #define BIG_ENDIAN 1
33 #define BYTE_ORDER 1
34 #endif
35
36 #define PUT_64BIT_LE(cp, value) do { \
37 (cp)[7] = (value) >> 56; \
38 (cp)[6] = (value) >> 48; \
39 (cp)[5] = (value) >> 40; \
40 (cp)[4] = (value) >> 32; \
41 (cp)[3] = (value) >> 24; \
42 (cp)[2] = (value) >> 16; \
43 (cp)[1] = (value) >> 8; \
44 (cp)[0] = (value); } while (0)
45
46 #define PUT_32BIT_LE(cp, value) do { \
47 (cp)[3] = (value) >> 24; \
48 (cp)[2] = (value) >> 16; \
49 (cp)[1] = (value) >> 8; \
50 (cp)[0] = (value); } while (0)
51
52 static uint8_t PADDING[MD4_BLOCK_LENGTH] = {
53 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
56 };
57
58 /*
59 * Start MD4 accumulation.
60 * Set bit count to 0 and buffer to mysterious initialization constants.
61 */
62 void
63 MD4Init(MD4_CTX *ctx)
64 {
65 ctx->count = 0;
66 ctx->state[0] = 0x67452301;
67 ctx->state[1] = 0xefcdab89;
68 ctx->state[2] = 0x98badcfe;
69 ctx->state[3] = 0x10325476;
70 }
71
72 /*
73 * Update context to reflect the concatenation of another buffer full
74 * of bytes.
75 */
76 void
77 MD4Update(MD4_CTX *ctx, const unsigned char *input, size_t len)
78 {
79 size_t have, need;
80
81 /* Check how many bytes we already have and how many more we need. */
82 have = (size_t)((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
83 need = MD4_BLOCK_LENGTH - have;
84
85 /* Update bitcount */
86 ctx->count += (uint64_t)len << 3;
87
88 if (len >= need) {
89 if (have != 0) {
90 memcpy(ctx->buffer + have, input, need);
91 MD4Transform(ctx->state, ctx->buffer);
92 input += need;
93 len -= need;
94 have = 0;
95 }
96
97 /* Process data in MD4_BLOCK_LENGTH-byte chunks. */
98 while (len >= MD4_BLOCK_LENGTH) {
99 MD4Transform(ctx->state, input);
100 input += MD4_BLOCK_LENGTH;
101 len -= MD4_BLOCK_LENGTH;
102 }
103 }
104
105 /* Handle any remaining bytes of data. */
106 if (len != 0)
107 memcpy(ctx->buffer + have, input, len);
108 }
109
110 /*
111 * Pad pad to 64-byte boundary with the bit pattern
112 * 1 0* (64-bit count of bits processed, MSB-first)
113 */
114 void
115 MD4Pad(MD4_CTX *ctx)
116 {
117 uint8_t count[8];
118 size_t padlen;
119
120 /* Convert count to 8 bytes in little endian order. */
121 PUT_64BIT_LE(count, ctx->count);
122
123 /* Pad out to 56 mod 64. */
124 padlen = MD4_BLOCK_LENGTH -
125 ((ctx->count >> 3) & (MD4_BLOCK_LENGTH - 1));
126 if (padlen < 1 + 8)
127 padlen += MD4_BLOCK_LENGTH;
128 MD4Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */
129 MD4Update(ctx, count, 8);
130 }
131
132 /*
133 * Final wrapup--call MD4Pad, fill in digest and zero out ctx.
134 */
135 void
136 MD4Final(unsigned char digest[MD4_DIGEST_LENGTH], MD4_CTX *ctx)
137 {
138 int i;
139
140 MD4Pad(ctx);
141 if (digest != NULL) {
142 for (i = 0; i < 4; i++)
143 PUT_32BIT_LE(digest + i * 4, ctx->state[i]);
144 memset(ctx, 0, sizeof(*ctx));
145 }
146 }
147
148
149 /* The three core functions - F1 is optimized somewhat */
150
151 /* #define F1(x, y, z) (x & y | ~x & z) */
152 #define F1(x, y, z) (z ^ (x & (y ^ z)))
153 #define F2(x, y, z) ((x & y) | (x & z) | (y & z))
154 #define F3(x, y, z) (x ^ y ^ z)
155
156 /* This is the central step in the MD4 algorithm. */
157 #define MD4STEP(f, w, x, y, z, data, s) \
158 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s) )
159
160 /*
161 * The core of the MD4 algorithm, this alters an existing MD4 hash to
162 * reflect the addition of 16 longwords of new data. MD4Update blocks
163 * the data and converts bytes into longwords for this routine.
164 */
165 void
166 MD4Transform(uint32_t state[4], const uint8_t block[MD4_BLOCK_LENGTH])
167 {
168 uint32_t a, b, c, d, in[MD4_BLOCK_LENGTH / 4];
169
170 #if BYTE_ORDER == LITTLE_ENDIAN
171 memcpy(in, block, sizeof(in));
172 #else
173 for (a = 0; a < MD4_BLOCK_LENGTH / 4; a++) {
174 in[a] = (uint32_t)(
175 (uint32_t)(block[a * 4 + 0]) |
176 (uint32_t)(block[a * 4 + 1]) << 8 |
177 (uint32_t)(block[a * 4 + 2]) << 16 |
178 (uint32_t)(block[a * 4 + 3]) << 24);
179 }
180 #endif
181
182 a = state[0];
183 b = state[1];
184 c = state[2];
185 d = state[3];
186
187 MD4STEP(F1, a, b, c, d, in[ 0], 3);
188 MD4STEP(F1, d, a, b, c, in[ 1], 7);
189 MD4STEP(F1, c, d, a, b, in[ 2], 11);
190 MD4STEP(F1, b, c, d, a, in[ 3], 19);
191 MD4STEP(F1, a, b, c, d, in[ 4], 3);
192 MD4STEP(F1, d, a, b, c, in[ 5], 7);
193 MD4STEP(F1, c, d, a, b, in[ 6], 11);
194 MD4STEP(F1, b, c, d, a, in[ 7], 19);
195 MD4STEP(F1, a, b, c, d, in[ 8], 3);
196 MD4STEP(F1, d, a, b, c, in[ 9], 7);
197 MD4STEP(F1, c, d, a, b, in[10], 11);
198 MD4STEP(F1, b, c, d, a, in[11], 19);
199 MD4STEP(F1, a, b, c, d, in[12], 3);
200 MD4STEP(F1, d, a, b, c, in[13], 7);
201 MD4STEP(F1, c, d, a, b, in[14], 11);
202 MD4STEP(F1, b, c, d, a, in[15], 19);
203
204 MD4STEP(F2, a, b, c, d, in[ 0] + 0x5a827999, 3);
205 MD4STEP(F2, d, a, b, c, in[ 4] + 0x5a827999, 5);
206 MD4STEP(F2, c, d, a, b, in[ 8] + 0x5a827999, 9);
207 MD4STEP(F2, b, c, d, a, in[12] + 0x5a827999, 13);
208 MD4STEP(F2, a, b, c, d, in[ 1] + 0x5a827999, 3);
209 MD4STEP(F2, d, a, b, c, in[ 5] + 0x5a827999, 5);
210 MD4STEP(F2, c, d, a, b, in[ 9] + 0x5a827999, 9);
211 MD4STEP(F2, b, c, d, a, in[13] + 0x5a827999, 13);
212 MD4STEP(F2, a, b, c, d, in[ 2] + 0x5a827999, 3);
213 MD4STEP(F2, d, a, b, c, in[ 6] + 0x5a827999, 5);
214 MD4STEP(F2, c, d, a, b, in[10] + 0x5a827999, 9);
215 MD4STEP(F2, b, c, d, a, in[14] + 0x5a827999, 13);
216 MD4STEP(F2, a, b, c, d, in[ 3] + 0x5a827999, 3);
217 MD4STEP(F2, d, a, b, c, in[ 7] + 0x5a827999, 5);
218 MD4STEP(F2, c, d, a, b, in[11] + 0x5a827999, 9);
219 MD4STEP(F2, b, c, d, a, in[15] + 0x5a827999, 13);
220
221 MD4STEP(F3, a, b, c, d, in[ 0] + 0x6ed9eba1, 3);
222 MD4STEP(F3, d, a, b, c, in[ 8] + 0x6ed9eba1, 9);
223 MD4STEP(F3, c, d, a, b, in[ 4] + 0x6ed9eba1, 11);
224 MD4STEP(F3, b, c, d, a, in[12] + 0x6ed9eba1, 15);
225 MD4STEP(F3, a, b, c, d, in[ 2] + 0x6ed9eba1, 3);
226 MD4STEP(F3, d, a, b, c, in[10] + 0x6ed9eba1, 9);
227 MD4STEP(F3, c, d, a, b, in[ 6] + 0x6ed9eba1, 11);
228 MD4STEP(F3, b, c, d, a, in[14] + 0x6ed9eba1, 15);
229 MD4STEP(F3, a, b, c, d, in[ 1] + 0x6ed9eba1, 3);
230 MD4STEP(F3, d, a, b, c, in[ 9] + 0x6ed9eba1, 9);
231 MD4STEP(F3, c, d, a, b, in[ 5] + 0x6ed9eba1, 11);
232 MD4STEP(F3, b, c, d, a, in[13] + 0x6ed9eba1, 15);
233 MD4STEP(F3, a, b, c, d, in[ 3] + 0x6ed9eba1, 3);
234 MD4STEP(F3, d, a, b, c, in[11] + 0x6ed9eba1, 9);
235 MD4STEP(F3, c, d, a, b, in[ 7] + 0x6ed9eba1, 11);
236 MD4STEP(F3, b, c, d, a, in[15] + 0x6ed9eba1, 15);
237
238 state[0] += a;
239 state[1] += b;
240 state[2] += c;
241 state[3] += d;
242 }