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.
22 #include "../stdint.msvc.h"
\r
28 * The basic MD4 functions.
30 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
31 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
32 #define H(x, y, z) ((x) ^ (y) ^ (z))
35 * The MD4 transformation for all four rounds.
37 #define STEP(f, a, b, c, d, x, s) \
38 (a) += f((b), (c), (d)) + (x); \
39 (a) = ((a) << (s)) | ((a) >> (32 - (s)))
43 * SET reads 4 input bytes in little-endian byte order and stores them
44 * in a properly aligned word in host byte order.
46 * The check for little-endian architectures which tolerate unaligned
47 * memory accesses is just an optimization. Nothing will break if it
50 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
52 (*(const uint_fast32_t *)&ptr[(n) * 4])
58 (uint_fast32_t)ptr[(n) * 4] | \
59 ((uint_fast32_t)ptr[(n) * 4 + 1] << 8) | \
60 ((uint_fast32_t)ptr[(n) * 4 + 2] << 16) | \
61 ((uint_fast32_t)ptr[(n) * 4 + 3] << 24))
67 * This processes one or more 64-byte data blocks, but does NOT update
68 * the bit counters. There're no alignment requirements.
70 static const void *body(struct md4_context *ctx, const void *data, size_t size)
72 const unsigned char *ptr;
74 uint32_t saved_a, saved_b, saved_c, saved_d;
90 STEP(F, a, b, c, d, SET( 0), 3);
91 STEP(F, d, a, b, c, SET( 1), 7);
92 STEP(F, c, d, a, b, SET( 2), 11);
93 STEP(F, b, c, d, a, SET( 3), 19);
95 STEP(F, a, b, c, d, SET( 4), 3);
96 STEP(F, d, a, b, c, SET( 5), 7);
97 STEP(F, c, d, a, b, SET( 6), 11);
98 STEP(F, b, c, d, a, SET( 7), 19);
100 STEP(F, a, b, c, d, SET( 8), 3);
101 STEP(F, d, a, b, c, SET( 9), 7);
102 STEP(F, c, d, a, b, SET(10), 11);
103 STEP(F, b, c, d, a, SET(11), 19);
105 STEP(F, a, b, c, d, SET(12), 3);
106 STEP(F, d, a, b, c, SET(13), 7);
107 STEP(F, c, d, a, b, SET(14), 11);
108 STEP(F, b, c, d, a, SET(15), 19);
110 STEP(G, a, b, c, d, GET( 0) + 0x5A827999, 3);
111 STEP(G, d, a, b, c, GET( 4) + 0x5A827999, 5);
112 STEP(G, c, d, a, b, GET( 8) + 0x5A827999, 9);
113 STEP(G, b, c, d, a, GET(12) + 0x5A827999, 13);
115 STEP(G, a, b, c, d, GET( 1) + 0x5A827999, 3);
116 STEP(G, d, a, b, c, GET( 5) + 0x5A827999, 5);
117 STEP(G, c, d, a, b, GET( 9) + 0x5A827999, 9);
118 STEP(G, b, c, d, a, GET(13) + 0x5A827999, 13);
120 STEP(G, a, b, c, d, GET( 2) + 0x5A827999, 3);
121 STEP(G, d, a, b, c, GET( 6) + 0x5A827999, 5);
122 STEP(G, c, d, a, b, GET(10) + 0x5A827999, 9);
123 STEP(G, b, c, d, a, GET(14) + 0x5A827999, 13);
125 STEP(G, a, b, c, d, GET( 3) + 0x5A827999, 3);
126 STEP(G, d, a, b, c, GET( 7) + 0x5A827999, 5);
127 STEP(G, c, d, a, b, GET(11) + 0x5A827999, 9);
128 STEP(G, b, c, d, a, GET(15) + 0x5A827999, 13);
130 STEP(H, a, b, c, d, GET( 0) + 0x6ED9EBA1, 3);
131 STEP(H, d, a, b, c, GET( 8) + 0x6ED9EBA1, 9);
132 STEP(H, c, d, a, b, GET( 4) + 0x6ED9EBA1, 11);
133 STEP(H, b, c, d, a, GET(12) + 0x6ED9EBA1, 15);
135 STEP(H, a, b, c, d, GET( 2) + 0x6ED9EBA1, 3);
136 STEP(H, d, a, b, c, GET(10) + 0x6ED9EBA1, 9);
137 STEP(H, c, d, a, b, GET( 6) + 0x6ED9EBA1, 11);
138 STEP(H, b, c, d, a, GET(14) + 0x6ED9EBA1, 15);
140 STEP(H, a, b, c, d, GET( 1) + 0x6ED9EBA1, 3);
141 STEP(H, d, a, b, c, GET( 9) + 0x6ED9EBA1, 9);
142 STEP(H, c, d, a, b, GET( 5) + 0x6ED9EBA1, 11);
143 STEP(H, b, c, d, a, GET(13) + 0x6ED9EBA1, 15);
145 STEP(H, a, b, c, d, GET( 3) + 0x6ED9EBA1, 3);
146 STEP(H, d, a, b, c, GET(11) + 0x6ED9EBA1, 9);
147 STEP(H, c, d, a, b, GET( 7) + 0x6ED9EBA1, 11);
148 STEP(H, b, c, d, a, GET(15) + 0x6ED9EBA1, 15);
156 } while (size -= 64);
166 void md4_init(struct md4_context *ctx)
177 void md4_update(struct md4_context *ctx, const void *data, size_t size)
180 uint_fast32_t saved_lo;
181 unsigned long used, free;
184 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
186 ctx->hi += size >> 29;
188 used = saved_lo & 0x3f;
194 memcpy(&ctx->buffer[used], data, size);
198 memcpy(&ctx->buffer[used], data, free);
199 data = (const unsigned char *) data + free;
201 body(ctx, ctx->buffer, 64);
205 data = body(ctx, data, size & ~(unsigned long)0x3f);
209 memcpy(ctx->buffer, data, size);
212 void md4_final(struct md4_context *ctx, unsigned char result[MD4_RESULTLEN])
215 unsigned long used, free;
217 used = ctx->lo & 0x3f;
219 ctx->buffer[used++] = 0x80;
224 memset(&ctx->buffer[used], 0, free);
225 body(ctx, ctx->buffer, 64);
230 memset(&ctx->buffer[used], 0, free - 8);
233 ctx->buffer[56] = ctx->lo;
234 ctx->buffer[57] = ctx->lo >> 8;
235 ctx->buffer[58] = ctx->lo >> 16;
236 ctx->buffer[59] = ctx->lo >> 24;
237 ctx->buffer[60] = ctx->hi;
238 ctx->buffer[61] = ctx->hi >> 8;
239 ctx->buffer[62] = ctx->hi >> 16;
240 ctx->buffer[63] = ctx->hi >> 24;
242 body(ctx, ctx->buffer, 64);
245 result[1] = ctx->a >> 8;
246 result[2] = ctx->a >> 16;
247 result[3] = ctx->a >> 24;
249 result[5] = ctx->b >> 8;
250 result[6] = ctx->b >> 16;
251 result[7] = ctx->b >> 24;
253 result[9] = ctx->c >> 8;
254 result[10] = ctx->c >> 16;
255 result[11] = ctx->c >> 24;
257 result[13] = ctx->d >> 8;
258 result[14] = ctx->d >> 16;
259 result[15] = ctx->d >> 24;
261 memset(ctx, 0, sizeof(*ctx));
264 void md4_get_digest(const void *data, size_t size,
265 unsigned char result[MD4_RESULTLEN])
267 struct md4_context ctx;
270 md4_update(&ctx, data, size);
271 md4_final(&ctx, result);
274 static void hash_method_init_md4(void *context)
278 static void hash_method_loop_md4(void *context, const void *data, size_t size)
280 md4_update(context, data, size);
283 static void hash_method_result_md4(void *context, unsigned char *result_r)
285 md4_final(context, result_r);
288 const struct hash_method hash_method_md4 = {
290 sizeof(struct md4_context),
293 hash_method_init_md4,
294 hash_method_loop_md4,
295 hash_method_result_md4