48 static inline winpr_MD4_u32plus F(winpr_MD4_u32plus x, winpr_MD4_u32plus y, winpr_MD4_u32plus z)
50 return ((z) ^ ((x) & ((y) ^ (z))));
52 static inline winpr_MD4_u32plus G(winpr_MD4_u32plus x, winpr_MD4_u32plus y, winpr_MD4_u32plus z)
54 return (((x) & ((y) | (z))) | ((y) & (z)));
56 static inline winpr_MD4_u32plus H(winpr_MD4_u32plus x, winpr_MD4_u32plus y, winpr_MD4_u32plus z)
58 return ((x) ^ (y) ^ (z));
64 #define STEP(f, a, b, c, d, x, s) \
65 (a) += f((b), (c), (d)) + (x); \
66 (a) = (((a) << (s)) | (((a)&0xffffffff) >> (32 - (s))));
83 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
84 #define SET(n) (*(const winpr_MD4_u32plus*)&ptr[4ULL * (n)])
88 (ctx->block[(n)] = (winpr_MD4_u32plus)ptr[4ULL * (n)] | \
89 ((winpr_MD4_u32plus)ptr[4ULL * (n) + 1] << 8) | \
90 ((winpr_MD4_u32plus)ptr[4ULL * (n) + 2] << 16) | \
91 ((winpr_MD4_u32plus)ptr[4ULL * (n) + 3] << 24))
92 #define GET(n) (ctx->block[(n)])
99 static const void* body(
WINPR_MD4_CTX* ctx,
const void* data,
unsigned long size)
101 const winpr_MD4_u32plus ac1 = 0x5a827999;
102 const winpr_MD4_u32plus ac2 = 0x6ed9eba1;
104 const unsigned char* ptr = (
const unsigned char*)data;
106 winpr_MD4_u32plus a = ctx->a;
107 winpr_MD4_u32plus b = ctx->b;
108 winpr_MD4_u32plus c = ctx->c;
109 winpr_MD4_u32plus d = ctx->d;
113 const winpr_MD4_u32plus saved_a = a;
114 const winpr_MD4_u32plus saved_b = b;
115 const winpr_MD4_u32plus saved_c = c;
116 const winpr_MD4_u32plus saved_d = d;
119 STEP(F, a, b, c, d, SET(0), 3)
120 STEP(F, d, a, b, c, SET(1), 7)
121 STEP(F, c, d, a, b, SET(2), 11)
122 STEP(F, b, c, d, a, SET(3), 19)
123 STEP(F, a, b, c, d, SET(4), 3)
124 STEP(F, d, a, b, c, SET(5), 7)
125 STEP(F, c, d, a, b, SET(6), 11)
126 STEP(F, b, c, d, a, SET(7), 19)
127 STEP(F, a, b, c, d, SET(8), 3)
128 STEP(F, d, a, b, c, SET(9), 7)
129 STEP(F, c, d, a, b, SET(10), 11)
130 STEP(F, b, c, d, a, SET(11), 19)
131 STEP(F, a, b, c, d, SET(12), 3)
132 STEP(F, d, a, b, c, SET(13), 7)
133 STEP(F, c, d, a, b, SET(14), 11)
134 STEP(F, b, c, d, a, SET(15), 19)
137 STEP(G, a, b, c, d, GET(0) + ac1, 3)
138 STEP(G, d, a, b, c, GET(4) + ac1, 5)
139 STEP(G, c, d, a, b, GET(8) + ac1, 9)
140 STEP(G, b, c, d, a, GET(12) + ac1, 13)
141 STEP(G, a, b, c, d, GET(1) + ac1, 3)
142 STEP(G, d, a, b, c, GET(5) + ac1, 5)
143 STEP(G, c, d, a, b, GET(9) + ac1, 9)
144 STEP(G, b, c, d, a, GET(13) + ac1, 13)
145 STEP(G, a, b, c, d, GET(2) + ac1, 3)
146 STEP(G, d, a, b, c, GET(6) + ac1, 5)
147 STEP(G, c, d, a, b, GET(10) + ac1, 9)
148 STEP(G, b, c, d, a, GET(14) + ac1, 13)
149 STEP(G, a, b, c, d, GET(3) + ac1, 3)
150 STEP(G, d, a, b, c, GET(7) + ac1, 5)
151 STEP(G, c, d, a, b, GET(11) + ac1, 9)
152 STEP(G, b, c, d, a, GET(15) + ac1, 13)
155 STEP(H, a, b, c, d, GET(0) + ac2, 3)
156 STEP(H, d, a, b, c, GET(8) + ac2, 9)
157 STEP(H, c, d, a, b, GET(4) + ac2, 11)
158 STEP(H, b, c, d, a, GET(12) + ac2, 15)
159 STEP(H, a, b, c, d, GET(2) + ac2, 3)
160 STEP(H, d, a, b, c, GET(10) + ac2, 9)
161 STEP(H, c, d, a, b, GET(6) + ac2, 11)
162 STEP(H, b, c, d, a, GET(14) + ac2, 15)
163 STEP(H, a, b, c, d, GET(1) + ac2, 3)
164 STEP(H, d, a, b, c, GET(9) + ac2, 9)
165 STEP(H, c, d, a, b, GET(5) + ac2, 11)
166 STEP(H, b, c, d, a, GET(13) + ac2, 15)
167 STEP(H, a, b, c, d, GET(3) + ac2, 3)
168 STEP(H, d, a, b, c, GET(11) + ac2, 9)
169 STEP(H, c, d, a, b, GET(7) + ac2, 11)
170 STEP(H, b, c, d, a, GET(15) + ac2, 15)
178 } while (size -= 64);
199 void winpr_MD4_Update(
WINPR_MD4_CTX* ctx,
const void* data,
unsigned long size)
201 winpr_MD4_u32plus saved_lo = ctx->lo;
202 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
204 ctx->hi += size >> 29;
206 unsigned long used = saved_lo & 0x3f;
210 unsigned long available = 64 - used;
212 if (size < available)
214 memcpy(&ctx->buffer[used], data, size);
218 memcpy(&ctx->buffer[used], data, available);
219 data = (
const unsigned char*)data + available;
221 body(ctx, ctx->buffer, 64);
226 data = body(ctx, data, size & ~(
unsigned long)0x3f);
230 memcpy(ctx->buffer, data, size);
233 static inline void mdOUT(
unsigned char* dst, winpr_MD4_u32plus src)
235 (dst)[0] = (
unsigned char)(src);
236 (dst)[1] = (
unsigned char)((src) >> 8);
237 (dst)[2] = (
unsigned char)((src) >> 16);
238 (dst)[3] = (
unsigned char)((src) >> 24);
241 void winpr_MD4_Final(
unsigned char* result,
WINPR_MD4_CTX* ctx)
243 unsigned long used = ctx->lo & 0x3f;
245 ctx->buffer[used++] = 0x80;
247 unsigned long available = 64 - used;
251 memset(&ctx->buffer[used], 0, available);
252 body(ctx, ctx->buffer, 64);
257 memset(&ctx->buffer[used], 0, available - 8);
260 mdOUT(&ctx->buffer[56], ctx->lo);
261 mdOUT(&ctx->buffer[60], ctx->hi);
263 body(ctx, ctx->buffer, 64);
265 mdOUT(&result[0], ctx->a);
266 mdOUT(&result[4], ctx->b);
267 mdOUT(&result[8], ctx->c);
268 mdOUT(&result[12], ctx->d);
270 memset(ctx, 0,
sizeof(*ctx));