Ok, the long awaited config wizard is here (at least in a very basic state). There...
[quassel.git] / src / contrib / libqxt-2007-10-24 / src / crypto / thirdparty / md4.cpp
1 /*
2  * MD4 (RFC-1320) message digest.
3  * Modified from MD5 code by Andrey Panin <pazke@donpac.ru>
4  *
5  * Written by Solar Designer <solar@openwall.com> in 2001, and placed in
6  * the public domain.  There's absolutely no warranty.
7  *
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.
12  *
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.
16  */
17
18 #include "md4.h"
19
20 #include <string.h>
21
22 /*
23  * The basic MD4 functions.
24  */
25 #define F(x, y, z)      ((z) ^ ((x) & ((y) ^ (z))))
26 #define G(x, y, z)      (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
27 #define H(x, y, z)      ((x) ^ (y) ^ (z))
28
29 /*
30  * The MD4 transformation for all four rounds.
31  */
32 #define STEP(f, a, b, c, d, x, s) \
33         (a) += f((b), (c), (d)) + (x);   \
34         (a) = ((a) << (s)) | ((a) >> (32 - (s)))
35
36
37 /*
38  * SET reads 4 input bytes in little-endian byte order and stores them
39  * in a properly aligned word in host byte order.
40  *
41  * The check for little-endian architectures which tolerate unaligned
42  * memory accesses is just an optimization.  Nothing will break if it
43  * doesn't work.
44  */
45 #if defined(__i386__) || defined(__x86_64__)
46 #define SET(n) \
47         (*(const quint32 *)&ptr[(n) * 4])
48 #define GET(n) \
49         SET(n)
50 #else
51 #define SET(n) \
52         (ctx->block[(n)] = \
53         (quint32)ptr[(n) * 4] | \
54         ((quint32)ptr[(n) * 4 + 1] << 8) | \
55         ((quint32)ptr[(n) * 4 + 2] << 16) | \
56         ((quint32)ptr[(n) * 4 + 3] << 24))
57 #define GET(n) \
58         (ctx->block[(n)])
59 #endif
60
61 /*
62  * This processes one or more 64-byte data blocks, but does NOT update
63  * the bit counters.  There're no alignment requirements.
64  */
65 static const unsigned char *body(struct md4_context *ctx, const unsigned char *data, size_t size)
66 {
67         const unsigned char *ptr;
68         quint32 a, b, c, d;
69         quint32 saved_a, saved_b, saved_c, saved_d;
70
71         ptr = data;
72
73         a = ctx->a;
74         b = ctx->b;
75         c = ctx->c;
76         d = ctx->d;
77
78         do {
79                 saved_a = a;
80                 saved_b = b;
81                 saved_c = c;
82                 saved_d = d;
83
84 /* Round 1 */
85                 STEP(F, a, b, c, d, SET( 0),  3);
86                 STEP(F, d, a, b, c, SET( 1),  7);
87                 STEP(F, c, d, a, b, SET( 2), 11);
88                 STEP(F, b, c, d, a, SET( 3), 19);
89
90                 STEP(F, a, b, c, d, SET( 4),  3);
91                 STEP(F, d, a, b, c, SET( 5),  7);
92                 STEP(F, c, d, a, b, SET( 6), 11);
93                 STEP(F, b, c, d, a, SET( 7), 19);
94
95                 STEP(F, a, b, c, d, SET( 8),  3);
96                 STEP(F, d, a, b, c, SET( 9),  7);
97                 STEP(F, c, d, a, b, SET(10), 11);
98                 STEP(F, b, c, d, a, SET(11), 19);
99
100                 STEP(F, a, b, c, d, SET(12),  3);
101                 STEP(F, d, a, b, c, SET(13),  7);
102                 STEP(F, c, d, a, b, SET(14), 11);
103                 STEP(F, b, c, d, a, SET(15), 19);
104 /* Round 2 */
105                 STEP(G, a, b, c, d, GET( 0) + 0x5A827999,  3);
106                 STEP(G, d, a, b, c, GET( 4) + 0x5A827999,  5);
107                 STEP(G, c, d, a, b, GET( 8) + 0x5A827999,  9);
108                 STEP(G, b, c, d, a, GET(12) + 0x5A827999, 13);
109
110                 STEP(G, a, b, c, d, GET( 1) + 0x5A827999,  3);
111                 STEP(G, d, a, b, c, GET( 5) + 0x5A827999,  5);
112                 STEP(G, c, d, a, b, GET( 9) + 0x5A827999,  9);
113                 STEP(G, b, c, d, a, GET(13) + 0x5A827999, 13);
114
115                 STEP(G, a, b, c, d, GET( 2) + 0x5A827999,  3);
116                 STEP(G, d, a, b, c, GET( 6) + 0x5A827999,  5);
117                 STEP(G, c, d, a, b, GET(10) + 0x5A827999,  9);
118                 STEP(G, b, c, d, a, GET(14) + 0x5A827999, 13);
119
120                 STEP(G, a, b, c, d, GET( 3) + 0x5A827999,  3);
121                 STEP(G, d, a, b, c, GET( 7) + 0x5A827999,  5);
122                 STEP(G, c, d, a, b, GET(11) + 0x5A827999,  9);
123                 STEP(G, b, c, d, a, GET(15) + 0x5A827999, 13);
124 /* Round 3 */
125                 STEP(H, a, b, c, d, GET( 0) + 0x6ED9EBA1,  3);
126                 STEP(H, d, a, b, c, GET( 8) + 0x6ED9EBA1,  9);
127                 STEP(H, c, d, a, b, GET( 4) + 0x6ED9EBA1, 11);
128                 STEP(H, b, c, d, a, GET(12) + 0x6ED9EBA1, 15);
129
130                 STEP(H, a, b, c, d, GET( 2) + 0x6ED9EBA1,  3);
131                 STEP(H, d, a, b, c, GET(10) + 0x6ED9EBA1,  9);
132                 STEP(H, c, d, a, b, GET( 6) + 0x6ED9EBA1, 11);
133                 STEP(H, b, c, d, a, GET(14) + 0x6ED9EBA1, 15);
134
135                 STEP(H, a, b, c, d, GET( 1) + 0x6ED9EBA1,  3);
136                 STEP(H, d, a, b, c, GET( 9) + 0x6ED9EBA1,  9);
137                 STEP(H, c, d, a, b, GET( 5) + 0x6ED9EBA1, 11);
138                 STEP(H, b, c, d, a, GET(13) + 0x6ED9EBA1, 15);
139
140                 STEP(H, a, b, c, d, GET( 3) + 0x6ED9EBA1,  3);
141                 STEP(H, d, a, b, c, GET(11) + 0x6ED9EBA1,  9);
142                 STEP(H, c, d, a, b, GET( 7) + 0x6ED9EBA1, 11);
143                 STEP(H, b, c, d, a, GET(15) + 0x6ED9EBA1, 15);
144
145                 a += saved_a;
146                 b += saved_b;
147                 c += saved_c;
148                 d += saved_d;
149
150                 ptr += 64;
151         } while (size -= 64);
152
153         ctx->a = a;
154         ctx->b = b;
155         ctx->c = c;
156         ctx->d = d;
157
158         return ptr;
159 }
160
161 static void md4_init(struct md4_context *ctx)
162 {
163         ctx->a = 0x67452301;
164         ctx->b = 0xefcdab89;
165         ctx->c = 0x98badcfe;
166         ctx->d = 0x10325476;
167
168         ctx->lo = 0;
169         ctx->hi = 0;
170 }
171
172 static void md4_update(struct md4_context *ctx, const unsigned char *data, size_t size)
173 {
174         /* @UNSAFE */
175         quint32 saved_lo;
176         unsigned long used, free;
177
178         saved_lo = ctx->lo;
179         if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
180                 ctx->hi++;
181         ctx->hi += size >> 29;
182
183         used = saved_lo & 0x3f;
184
185         if (used) {
186                 free = 64 - used;
187
188                 if (size < free) {
189                         memcpy(&ctx->buffer[used], data, size);
190                         return;
191                 }
192
193                 memcpy(&ctx->buffer[used], data, free);
194                 data = (const unsigned char *) data + free;
195                 size -= free;
196                 body(ctx, ctx->buffer, 64);
197         }
198
199         if (size >= 64) {
200                 data = body(ctx, data, size & ~(unsigned long)0x3f);
201                 size &= 0x3f;
202         }
203
204         memcpy(ctx->buffer, data, size);
205 }
206
207 static void md4_final(struct md4_context *ctx, unsigned char result[MD4_RESULTLEN])
208 {
209         /* @UNSAFE */
210         unsigned long used, free;
211
212         used = ctx->lo & 0x3f;
213
214         ctx->buffer[used++] = 0x80;
215
216         free = 64 - used;
217
218         if (free < 8) {
219                 memset(&ctx->buffer[used], 0, free);
220                 body(ctx, ctx->buffer, 64);
221                 used = 0;
222                 free = 64;
223         }
224
225         memset(&ctx->buffer[used], 0, free - 8);
226
227         ctx->lo <<= 3;
228         ctx->buffer[56] = ctx->lo;
229         ctx->buffer[57] = ctx->lo >> 8;
230         ctx->buffer[58] = ctx->lo >> 16;
231         ctx->buffer[59] = ctx->lo >> 24;
232         ctx->buffer[60] = ctx->hi;
233         ctx->buffer[61] = ctx->hi >> 8;
234         ctx->buffer[62] = ctx->hi >> 16;
235         ctx->buffer[63] = ctx->hi >> 24;
236
237         body(ctx, ctx->buffer, 64);
238
239         result[0] = ctx->a;
240         result[1] = ctx->a >> 8;
241         result[2] = ctx->a >> 16;
242         result[3] = ctx->a >> 24;
243         result[4] = ctx->b;
244         result[5] = ctx->b >> 8;
245         result[6] = ctx->b >> 16;
246         result[7] = ctx->b >> 24;
247         result[8] = ctx->c;
248         result[9] = ctx->c >> 8;
249         result[10] = ctx->c >> 16;
250         result[11] = ctx->c >> 24;
251         result[12] = ctx->d;
252         result[13] = ctx->d >> 8;
253         result[14] = ctx->d >> 16;
254         result[15] = ctx->d >> 24;
255
256         memset(ctx, 0, sizeof(*ctx));
257 }
258
259 #undef F
260 #undef G
261 #undef H