This source file includes following definitions.
- md4_init_ctx
- set_uint32
- md4_read_ctx
- md4_finish_ctx
- md4_buffer
- md4_process_bytes
- md4_process_block
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24
25 #include "md4.h"
26
27 #include <stdalign.h>
28 #include <stdint.h>
29 #include <string.h>
30 #include <sys/types.h>
31
32 #include <byteswap.h>
33 #ifdef WORDS_BIGENDIAN
34 # define SWAP(n) bswap_32 (n)
35 #else
36 # define SWAP(n) (n)
37 #endif
38
39
40
41 static const unsigned char fillbuf[64] = { 0x80, 0 };
42
43
44
45
46 void
47 md4_init_ctx (struct md4_ctx *ctx)
48 {
49 ctx->A = 0x67452301;
50 ctx->B = 0xefcdab89;
51 ctx->C = 0x98badcfe;
52 ctx->D = 0x10325476;
53
54 ctx->total[0] = ctx->total[1] = 0;
55 ctx->buflen = 0;
56 }
57
58
59
60
61 static void
62 set_uint32 (char *cp, uint32_t v)
63 {
64 memcpy (cp, &v, sizeof v);
65 }
66
67
68
69 void *
70 md4_read_ctx (const struct md4_ctx *ctx, void *resbuf)
71 {
72 char *r = resbuf;
73 set_uint32 (r + 0 * sizeof ctx->A, SWAP (ctx->A));
74 set_uint32 (r + 1 * sizeof ctx->B, SWAP (ctx->B));
75 set_uint32 (r + 2 * sizeof ctx->C, SWAP (ctx->C));
76 set_uint32 (r + 3 * sizeof ctx->D, SWAP (ctx->D));
77
78 return resbuf;
79 }
80
81
82
83 void *
84 md4_finish_ctx (struct md4_ctx *ctx, void *resbuf)
85 {
86
87 uint32_t bytes = ctx->buflen;
88 size_t pad;
89
90
91 ctx->total[0] += bytes;
92 if (ctx->total[0] < bytes)
93 ++ctx->total[1];
94
95 pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
96 memcpy (&((char*)ctx->buffer)[bytes], fillbuf, pad);
97
98
99 ctx->buffer[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3);
100 ctx->buffer[(bytes + pad) / 4 + 1] = SWAP ((ctx->total[1] << 3) |
101 (ctx->total[0] >> 29));
102
103
104 md4_process_block (ctx->buffer, bytes + pad + 8, ctx);
105
106 return md4_read_ctx (ctx, resbuf);
107 }
108
109
110
111
112
113 void *
114 md4_buffer (const char *buffer, size_t len, void *resblock)
115 {
116 struct md4_ctx ctx;
117
118
119 md4_init_ctx (&ctx);
120
121
122 md4_process_bytes (buffer, len, &ctx);
123
124
125 return md4_finish_ctx (&ctx, resblock);
126 }
127
128 void
129 md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx)
130 {
131
132
133 if (ctx->buflen != 0)
134 {
135 size_t left_over = ctx->buflen;
136 size_t add = 128 - left_over > len ? len : 128 - left_over;
137
138 memcpy (&((char*)ctx->buffer)[left_over], buffer, add);
139 ctx->buflen += add;
140
141 if (ctx->buflen > 64)
142 {
143 md4_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
144
145 ctx->buflen &= 63;
146
147 memcpy (ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63],
148 ctx->buflen);
149 }
150
151 buffer = (const char *) buffer + add;
152 len -= add;
153 }
154
155
156 if (len >= 64)
157 {
158 #if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned)
159 # define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (uint32_t) != 0)
160 if (UNALIGNED_P (buffer))
161 while (len > 64)
162 {
163 md4_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
164 buffer = (const char *) buffer + 64;
165 len -= 64;
166 }
167 else
168 #endif
169 {
170 md4_process_block (buffer, len & ~63, ctx);
171 buffer = (const char *) buffer + (len & ~63);
172 len &= 63;
173 }
174 }
175
176
177 if (len > 0)
178 {
179 size_t left_over = ctx->buflen;
180
181 memcpy (&((char*)ctx->buffer)[left_over], buffer, len);
182 left_over += len;
183 if (left_over >= 64)
184 {
185 md4_process_block (ctx->buffer, 64, ctx);
186 left_over -= 64;
187 memcpy (ctx->buffer, &ctx->buffer[16], left_over);
188 }
189 ctx->buflen = left_over;
190 }
191 }
192
193
194
195
196 #define K1 0x5a827999
197 #define K2 0x6ed9eba1
198
199
200 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
201 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
202 #define H(x, y, z) ((x) ^ (y) ^ (z))
203 #define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
204 #define R1(a,b,c,d,k,s) a=rol(a+F(b,c,d)+x[k],s);
205 #define R2(a,b,c,d,k,s) a=rol(a+G(b,c,d)+x[k]+K1,s);
206 #define R3(a,b,c,d,k,s) a=rol(a+H(b,c,d)+x[k]+K2,s);
207
208
209
210
211 void
212 md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx)
213 {
214 const uint32_t *words = buffer;
215 size_t nwords = len / sizeof (uint32_t);
216 const uint32_t *endp = words + nwords;
217 uint32_t x[16];
218 uint32_t A = ctx->A;
219 uint32_t B = ctx->B;
220 uint32_t C = ctx->C;
221 uint32_t D = ctx->D;
222 uint32_t lolen = len;
223
224
225
226
227 ctx->total[0] += lolen;
228 ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen);
229
230
231
232 while (words < endp)
233 {
234 int t;
235 for (t = 0; t < 16; t++)
236 {
237 x[t] = SWAP (*words);
238 words++;
239 }
240
241
242 R1 (A, B, C, D, 0, 3);
243 R1 (D, A, B, C, 1, 7);
244 R1 (C, D, A, B, 2, 11);
245 R1 (B, C, D, A, 3, 19);
246 R1 (A, B, C, D, 4, 3);
247 R1 (D, A, B, C, 5, 7);
248 R1 (C, D, A, B, 6, 11);
249 R1 (B, C, D, A, 7, 19);
250 R1 (A, B, C, D, 8, 3);
251 R1 (D, A, B, C, 9, 7);
252 R1 (C, D, A, B, 10, 11);
253 R1 (B, C, D, A, 11, 19);
254 R1 (A, B, C, D, 12, 3);
255 R1 (D, A, B, C, 13, 7);
256 R1 (C, D, A, B, 14, 11);
257 R1 (B, C, D, A, 15, 19);
258
259
260 R2 (A, B, C, D, 0, 3);
261 R2 (D, A, B, C, 4, 5);
262 R2 (C, D, A, B, 8, 9);
263 R2 (B, C, D, A, 12, 13);
264 R2 (A, B, C, D, 1, 3);
265 R2 (D, A, B, C, 5, 5);
266 R2 (C, D, A, B, 9, 9);
267 R2 (B, C, D, A, 13, 13);
268 R2 (A, B, C, D, 2, 3);
269 R2 (D, A, B, C, 6, 5);
270 R2 (C, D, A, B, 10, 9);
271 R2 (B, C, D, A, 14, 13);
272 R2 (A, B, C, D, 3, 3);
273 R2 (D, A, B, C, 7, 5);
274 R2 (C, D, A, B, 11, 9);
275 R2 (B, C, D, A, 15, 13);
276
277
278 R3 (A, B, C, D, 0, 3);
279 R3 (D, A, B, C, 8, 9);
280 R3 (C, D, A, B, 4, 11);
281 R3 (B, C, D, A, 12, 15);
282 R3 (A, B, C, D, 2, 3);
283 R3 (D, A, B, C, 10, 9);
284 R3 (C, D, A, B, 6, 11);
285 R3 (B, C, D, A, 14, 15);
286 R3 (A, B, C, D, 1, 3);
287 R3 (D, A, B, C, 9, 9);
288 R3 (C, D, A, B, 5, 11);
289 R3 (B, C, D, A, 13, 15);
290 R3 (A, B, C, D, 3, 3);
291 R3 (D, A, B, C, 11, 9);
292 R3 (C, D, A, B, 7, 11);
293 R3 (B, C, D, A, 15, 15);
294
295 A = ctx->A += A;
296 B = ctx->B += B;
297 C = ctx->C += C;
298 D = ctx->D += D;
299 }
300 }