Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/hashes/md4.c
5971 views
1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
2
*
3
* LibTomCrypt is a library that provides various cryptographic
4
* algorithms in a highly modular and flexible manner.
5
*
6
* The library is free for all purposes without any express
7
* guarantee it works.
8
*/
9
#include "tomcrypt.h"
10
11
/**
12
@param md4.c
13
Submitted by Dobes Vandermeer ([email protected])
14
*/
15
16
#ifdef LTC_MD4
17
18
const struct ltc_hash_descriptor md4_desc =
19
{
20
"md4",
21
6,
22
16,
23
64,
24
25
/* OID */
26
{ 1, 2, 840, 113549, 2, 4, },
27
6,
28
29
&md4_init,
30
&md4_process,
31
&md4_done,
32
&md4_test,
33
NULL
34
};
35
36
#define S11 3
37
#define S12 7
38
#define S13 11
39
#define S14 19
40
#define S21 3
41
#define S22 5
42
#define S23 9
43
#define S24 13
44
#define S31 3
45
#define S32 9
46
#define S33 11
47
#define S34 15
48
49
/* F, G and H are basic LTC_MD4 functions. */
50
#define F(x, y, z) (z ^ (x & (y ^ z)))
51
#define G(x, y, z) ((x & y) | (z & (x | y)))
52
#define H(x, y, z) ((x) ^ (y) ^ (z))
53
54
/* ROTATE_LEFT rotates x left n bits. */
55
#define ROTATE_LEFT(x, n) ROLc(x, n)
56
57
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
58
/* Rotation is separate from addition to prevent recomputation */
59
60
#define FF(a, b, c, d, x, s) { \
61
(a) += F ((b), (c), (d)) + (x); \
62
(a) = ROTATE_LEFT ((a), (s)); \
63
}
64
#define GG(a, b, c, d, x, s) { \
65
(a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
66
(a) = ROTATE_LEFT ((a), (s)); \
67
}
68
#define HH(a, b, c, d, x, s) { \
69
(a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
70
(a) = ROTATE_LEFT ((a), (s)); \
71
}
72
73
#ifdef LTC_CLEAN_STACK
74
static int _md4_compress(hash_state *md, unsigned char *buf)
75
#else
76
static int md4_compress(hash_state *md, unsigned char *buf)
77
#endif
78
{
79
ulong32 x[16], a, b, c, d;
80
int i;
81
82
/* copy state */
83
a = md->md4.state[0];
84
b = md->md4.state[1];
85
c = md->md4.state[2];
86
d = md->md4.state[3];
87
88
/* copy the state into 512-bits into W[0..15] */
89
for (i = 0; i < 16; i++) {
90
LOAD32L(x[i], buf + (4*i));
91
}
92
93
/* Round 1 */
94
FF (a, b, c, d, x[ 0], S11); /* 1 */
95
FF (d, a, b, c, x[ 1], S12); /* 2 */
96
FF (c, d, a, b, x[ 2], S13); /* 3 */
97
FF (b, c, d, a, x[ 3], S14); /* 4 */
98
FF (a, b, c, d, x[ 4], S11); /* 5 */
99
FF (d, a, b, c, x[ 5], S12); /* 6 */
100
FF (c, d, a, b, x[ 6], S13); /* 7 */
101
FF (b, c, d, a, x[ 7], S14); /* 8 */
102
FF (a, b, c, d, x[ 8], S11); /* 9 */
103
FF (d, a, b, c, x[ 9], S12); /* 10 */
104
FF (c, d, a, b, x[10], S13); /* 11 */
105
FF (b, c, d, a, x[11], S14); /* 12 */
106
FF (a, b, c, d, x[12], S11); /* 13 */
107
FF (d, a, b, c, x[13], S12); /* 14 */
108
FF (c, d, a, b, x[14], S13); /* 15 */
109
FF (b, c, d, a, x[15], S14); /* 16 */
110
111
/* Round 2 */
112
GG (a, b, c, d, x[ 0], S21); /* 17 */
113
GG (d, a, b, c, x[ 4], S22); /* 18 */
114
GG (c, d, a, b, x[ 8], S23); /* 19 */
115
GG (b, c, d, a, x[12], S24); /* 20 */
116
GG (a, b, c, d, x[ 1], S21); /* 21 */
117
GG (d, a, b, c, x[ 5], S22); /* 22 */
118
GG (c, d, a, b, x[ 9], S23); /* 23 */
119
GG (b, c, d, a, x[13], S24); /* 24 */
120
GG (a, b, c, d, x[ 2], S21); /* 25 */
121
GG (d, a, b, c, x[ 6], S22); /* 26 */
122
GG (c, d, a, b, x[10], S23); /* 27 */
123
GG (b, c, d, a, x[14], S24); /* 28 */
124
GG (a, b, c, d, x[ 3], S21); /* 29 */
125
GG (d, a, b, c, x[ 7], S22); /* 30 */
126
GG (c, d, a, b, x[11], S23); /* 31 */
127
GG (b, c, d, a, x[15], S24); /* 32 */
128
129
/* Round 3 */
130
HH (a, b, c, d, x[ 0], S31); /* 33 */
131
HH (d, a, b, c, x[ 8], S32); /* 34 */
132
HH (c, d, a, b, x[ 4], S33); /* 35 */
133
HH (b, c, d, a, x[12], S34); /* 36 */
134
HH (a, b, c, d, x[ 2], S31); /* 37 */
135
HH (d, a, b, c, x[10], S32); /* 38 */
136
HH (c, d, a, b, x[ 6], S33); /* 39 */
137
HH (b, c, d, a, x[14], S34); /* 40 */
138
HH (a, b, c, d, x[ 1], S31); /* 41 */
139
HH (d, a, b, c, x[ 9], S32); /* 42 */
140
HH (c, d, a, b, x[ 5], S33); /* 43 */
141
HH (b, c, d, a, x[13], S34); /* 44 */
142
HH (a, b, c, d, x[ 3], S31); /* 45 */
143
HH (d, a, b, c, x[11], S32); /* 46 */
144
HH (c, d, a, b, x[ 7], S33); /* 47 */
145
HH (b, c, d, a, x[15], S34); /* 48 */
146
147
148
/* Update our state */
149
md->md4.state[0] = md->md4.state[0] + a;
150
md->md4.state[1] = md->md4.state[1] + b;
151
md->md4.state[2] = md->md4.state[2] + c;
152
md->md4.state[3] = md->md4.state[3] + d;
153
154
return CRYPT_OK;
155
}
156
157
#ifdef LTC_CLEAN_STACK
158
static int md4_compress(hash_state *md, unsigned char *buf)
159
{
160
int err;
161
err = _md4_compress(md, buf);
162
burn_stack(sizeof(ulong32) * 20 + sizeof(int));
163
return err;
164
}
165
#endif
166
167
/**
168
Initialize the hash state
169
@param md The hash state you wish to initialize
170
@return CRYPT_OK if successful
171
*/
172
int md4_init(hash_state * md)
173
{
174
LTC_ARGCHK(md != NULL);
175
md->md4.state[0] = 0x67452301UL;
176
md->md4.state[1] = 0xefcdab89UL;
177
md->md4.state[2] = 0x98badcfeUL;
178
md->md4.state[3] = 0x10325476UL;
179
md->md4.length = 0;
180
md->md4.curlen = 0;
181
return CRYPT_OK;
182
}
183
184
/**
185
Process a block of memory though the hash
186
@param md The hash state
187
@param in The data to hash
188
@param inlen The length of the data (octets)
189
@return CRYPT_OK if successful
190
*/
191
HASH_PROCESS(md4_process, md4_compress, md4, 64)
192
193
/**
194
Terminate the hash to get the digest
195
@param md The hash state
196
@param out [out] The destination of the hash (16 bytes)
197
@return CRYPT_OK if successful
198
*/
199
int md4_done(hash_state * md, unsigned char *out)
200
{
201
int i;
202
203
LTC_ARGCHK(md != NULL);
204
LTC_ARGCHK(out != NULL);
205
206
if (md->md4.curlen >= sizeof(md->md4.buf)) {
207
return CRYPT_INVALID_ARG;
208
}
209
210
/* increase the length of the message */
211
md->md4.length += md->md4.curlen * 8;
212
213
/* append the '1' bit */
214
md->md4.buf[md->md4.curlen++] = (unsigned char)0x80;
215
216
/* if the length is currently above 56 bytes we append zeros
217
* then compress. Then we can fall back to padding zeros and length
218
* encoding like normal.
219
*/
220
if (md->md4.curlen > 56) {
221
while (md->md4.curlen < 64) {
222
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
223
}
224
md4_compress(md, md->md4.buf);
225
md->md4.curlen = 0;
226
}
227
228
/* pad upto 56 bytes of zeroes */
229
while (md->md4.curlen < 56) {
230
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
231
}
232
233
/* store length */
234
STORE64L(md->md4.length, md->md4.buf+56);
235
md4_compress(md, md->md4.buf);
236
237
/* copy output */
238
for (i = 0; i < 4; i++) {
239
STORE32L(md->md4.state[i], out+(4*i));
240
}
241
#ifdef LTC_CLEAN_STACK
242
zeromem(md, sizeof(hash_state));
243
#endif
244
return CRYPT_OK;
245
}
246
247
/**
248
Self-test the hash
249
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
250
*/
251
int md4_test(void)
252
{
253
#ifndef LTC_TEST
254
return CRYPT_NOP;
255
#else
256
static const struct md4_test_case {
257
const char *input;
258
unsigned char hash[16];
259
} tests[] = {
260
{ "",
261
{0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
262
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
263
{ "a",
264
{0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
265
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
266
{ "abc",
267
{0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
268
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
269
{ "message digest",
270
{0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
271
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
272
{ "abcdefghijklmnopqrstuvwxyz",
273
{0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
274
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
275
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
276
{0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
277
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
278
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
279
{0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
280
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
281
};
282
283
int i;
284
unsigned char tmp[16];
285
hash_state md;
286
287
for(i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
288
md4_init(&md);
289
md4_process(&md, (unsigned char *)tests[i].input, (unsigned long)strlen(tests[i].input));
290
md4_done(&md, tmp);
291
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD4", i)) {
292
return CRYPT_FAIL_TESTVECTOR;
293
}
294
295
}
296
return CRYPT_OK;
297
#endif
298
}
299
300
#endif
301
302