2 * MD4 (RFC-1320) message digest.
3 * Modified from MD5 code by Andrey Panin <pazke@donpac.ru>
5 * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
6 * the public domain. There's absolutely no warranty.
8 * This differs from Colin Plumb's older public domain implementation in
9 * that no 32-bit integer data type is required, there's no compile-time
10 * endianness configuration, and the function prototypes match OpenSSL's.
11 * The primary goals are portability and ease of use.
13 * This implementation is meant to be fast, but not as fast as possible.
14 * Some known optimizations are not included to reduce source code size
15 * and avoid compile-time configuration.
24 * The basic MD4 functions.
26 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
27 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
28 #define H(x, y, z) ((x) ^ (y) ^ (z))
31 * The MD4 transformation for all four rounds.
33 #define STEP(f, a, b, c, d, x, s) \
34 (a) += f((b), (c), (d)) + (x); \
35 (a) = ((a) << (s)) | ((a) >> (32 - (s)))
39 * SET reads 4 input bytes in little-endian byte order and stores them
40 * in a properly aligned word in host byte order.
42 * The check for little-endian architectures which tolerate unaligned
43 * memory accesses is just an optimization. Nothing will break if it
46 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
48 (*(const uint_fast32_t *)&ptr[(n) * 4])
54 (uint_fast32_t)ptr[(n) * 4] | \
55 ((uint_fast32_t)ptr[(n) * 4 + 1] << 8) | \
56 ((uint_fast32_t)ptr[(n) * 4 + 2] << 16) | \
57 ((uint_fast32_t)ptr[(n) * 4 + 3] << 24))
63 * This processes one or more 64-byte data blocks, but does NOT update
64 * the bit counters. There're no alignment requirements.
66 static const void *body(struct md4_context *ctx, const void *data, size_t size)
68 const unsigned char *ptr;
70 uint32_t saved_a, saved_b, saved_c, saved_d;
86 STEP(F, a, b, c, d, SET( 0), 3);
87 STEP(F, d, a, b, c, SET( 1), 7);
88 STEP(F, c, d, a, b, SET( 2), 11);
89 STEP(F, b, c, d, a, SET( 3), 19);
91 STEP(F, a, b, c, d, SET( 4), 3);
92 STEP(F, d, a, b, c, SET( 5), 7);
93 STEP(F, c, d, a, b, SET( 6), 11);
94 STEP(F, b, c, d, a, SET( 7), 19);
96 STEP(F, a, b, c, d, SET( 8), 3);
97 STEP(F, d, a, b, c, SET( 9), 7);
98 STEP(F, c, d, a, b, SET(10), 11);
99 STEP(F, b, c, d, a, SET(11), 19);
101 STEP(F, a, b, c, d, SET(12), 3);
102 STEP(F, d, a, b, c, SET(13), 7);
103 STEP(F, c, d, a, b, SET(14), 11);
104 STEP(F, b, c, d, a, SET(15), 19);
106 STEP(G, a, b, c, d, GET( 0) + 0x5A827999, 3);
107 STEP(G, d, a, b, c, GET( 4) + 0x5A827999, 5);
108 STEP(G, c, d, a, b, GET( 8) + 0x5A827999, 9);
109 STEP(G, b, c, d, a, GET(12) + 0x5A827999, 13);
111 STEP(G, a, b, c, d, GET( 1) + 0x5A827999, 3);
112 STEP(G, d, a, b, c, GET( 5) + 0x5A827999, 5);
113 STEP(G, c, d, a, b, GET( 9) + 0x5A827999, 9);
114 STEP(G, b, c, d, a, GET(13) + 0x5A827999, 13);
116 STEP(G, a, b, c, d, GET( 2) + 0x5A827999, 3);
117 STEP(G, d, a, b, c, GET( 6) + 0x5A827999, 5);
118 STEP(G, c, d, a, b, GET(10) + 0x5A827999, 9);
119 STEP(G, b, c, d, a, GET(14) + 0x5A827999, 13);
121 STEP(G, a, b, c, d, GET( 3) + 0x5A827999, 3);
122 STEP(G, d, a, b, c, GET( 7) + 0x5A827999, 5);
123 STEP(G, c, d, a, b, GET(11) + 0x5A827999, 9);
124 STEP(G, b, c, d, a, GET(15) + 0x5A827999, 13);
126 STEP(H, a, b, c, d, GET( 0) + 0x6ED9EBA1, 3);
127 STEP(H, d, a, b, c, GET( 8) + 0x6ED9EBA1, 9);
128 STEP(H, c, d, a, b, GET( 4) + 0x6ED9EBA1, 11);
129 STEP(H, b, c, d, a, GET(12) + 0x6ED9EBA1, 15);
131 STEP(H, a, b, c, d, GET( 2) + 0x6ED9EBA1, 3);
132 STEP(H, d, a, b, c, GET(10) + 0x6ED9EBA1, 9);
133 STEP(H, c, d, a, b, GET( 6) + 0x6ED9EBA1, 11);
134 STEP(H, b, c, d, a, GET(14) + 0x6ED9EBA1, 15);
136 STEP(H, a, b, c, d, GET( 1) + 0x6ED9EBA1, 3);
137 STEP(H, d, a, b, c, GET( 9) + 0x6ED9EBA1, 9);
138 STEP(H, c, d, a, b, GET( 5) + 0x6ED9EBA1, 11);
139 STEP(H, b, c, d, a, GET(13) + 0x6ED9EBA1, 15);
141 STEP(H, a, b, c, d, GET( 3) + 0x6ED9EBA1, 3);
142 STEP(H, d, a, b, c, GET(11) + 0x6ED9EBA1, 9);
143 STEP(H, c, d, a, b, GET( 7) + 0x6ED9EBA1, 11);
144 STEP(H, b, c, d, a, GET(15) + 0x6ED9EBA1, 15);
152 } while (size -= 64);
162 void md4_init(struct md4_context *ctx)
173 void md4_update(struct md4_context *ctx, const void *data, size_t size)
176 uint_fast32_t saved_lo;
177 unsigned long used, free;
180 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
182 ctx->hi += size >> 29;
184 used = saved_lo & 0x3f;
190 memcpy(&ctx->buffer[used], data, size);
194 memcpy(&ctx->buffer[used], data, free);
195 data = (const unsigned char *) data + free;
197 body(ctx, ctx->buffer, 64);
201 data = body(ctx, data, size & ~(unsigned long)0x3f);
205 memcpy(ctx->buffer, data, size);
208 void md4_final(struct md4_context *ctx, unsigned char result[MD4_RESULTLEN])
211 unsigned long used, free;
213 used = ctx->lo & 0x3f;
215 ctx->buffer[used++] = 0x80;
220 memset(&ctx->buffer[used], 0, free);
221 body(ctx, ctx->buffer, 64);
226 memset(&ctx->buffer[used], 0, free - 8);
229 ctx->buffer[56] = ctx->lo;
230 ctx->buffer[57] = ctx->lo >> 8;
231 ctx->buffer[58] = ctx->lo >> 16;
232 ctx->buffer[59] = ctx->lo >> 24;
233 ctx->buffer[60] = ctx->hi;
234 ctx->buffer[61] = ctx->hi >> 8;
235 ctx->buffer[62] = ctx->hi >> 16;
236 ctx->buffer[63] = ctx->hi >> 24;
238 body(ctx, ctx->buffer, 64);
241 result[1] = ctx->a >> 8;
242 result[2] = ctx->a >> 16;
243 result[3] = ctx->a >> 24;
245 result[5] = ctx->b >> 8;
246 result[6] = ctx->b >> 16;
247 result[7] = ctx->b >> 24;
249 result[9] = ctx->c >> 8;
250 result[10] = ctx->c >> 16;
251 result[11] = ctx->c >> 24;
253 result[13] = ctx->d >> 8;
254 result[14] = ctx->d >> 16;
255 result[15] = ctx->d >> 24;
257 memset(ctx, 0, sizeof(*ctx));
260 void md4_get_digest(const void *data, size_t size,
261 unsigned char result[MD4_RESULTLEN])
263 struct md4_context ctx;
266 md4_update(&ctx, data, size);
267 md4_final(&ctx, result);
270 static void hash_method_init_md4(void *context)
274 static void hash_method_loop_md4(void *context, const void *data, size_t size)
276 md4_update(context, data, size);
279 static void hash_method_result_md4(void *context, unsigned char *result_r)
281 md4_final(context, result_r);
284 const struct hash_method hash_method_md4 = {
286 sizeof(struct md4_context),
289 hash_method_init_md4,
290 hash_method_loop_md4,
291 hash_method_result_md4