152783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o/*
252783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * dirhash.c -- Calculate the hash of a directory entry
352783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o *
452783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * Copyright (c) 2001  Daniel Phillips
5efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
652783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * Copyright (c) 2002 Theodore Ts'o.
752783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o *
852783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * %Begin-Header%
9543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
10543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
1152783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * %End-Header%
1252783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o */
1352783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o
14d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h"
1552783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o#include <stdio.h>
16d3f917989badf78d1f97654e46d60d1f3d25cd17Theodore Ts'o#include <string.h>
1752783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o
1852783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o#include "ext2_fs.h"
1952783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o#include "ext2fs.h"
2052783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o
21b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o/*
22b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o * Keyed 32-bit hash function using TEA in a Davis-Meyer function
23b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o *   H0 = Key
24b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o *   Hi = E Mi(Hi-1) + Hi-1
25b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o *
26b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o * (see Applied Cryptography, 2nd edition, p448).
27b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o *
28b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
29efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
30b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o * This code is made available under the terms of the GPL
31b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o */
32b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o#define DELTA 0x9E3779B9
33b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
34b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'ostatic void TEA_transform(__u32 buf[4], __u32 const in[])
35b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o{
36b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	__u32	sum = 0;
37b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	__u32	b0 = buf[0], b1 = buf[1];
38b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
39b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	int	n = 16;
40b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
41efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	do {
42efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		sum += DELTA;
43efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
44efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
45b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	} while(--n);
46b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
47b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	buf[0] += b0;
48b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	buf[1] += b1;
49b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o}
50b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
51503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o/* F, G and H are basic MD4 functions: selection, majority, parity */
52503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
53503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
54503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define H(x, y, z) ((x) ^ (y) ^ (z))
55503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
56503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o/*
57503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * The generic round function.  The application is so specific that
58503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * we don't bother protecting all the arguments with parens, as is generally
59503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * good macro practice, in favor of extra legibility.
60503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * Rotation is separate from addition to prevent recomputation
61503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o */
62503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define ROUND(f, a, b, c, d, x, s)	\
63503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
64503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define K1 0
65503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define K2 013240474631UL
66503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#define K3 015666365641UL
67503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
68503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o/*
69503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * Basic cut-down MD4 transform.  Returns only 32 bits of result.
70503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o */
71b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'ostatic void halfMD4Transform (__u32 buf[4], __u32 const in[])
72503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o{
73503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
74503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
75503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	/* Round 1 */
76503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, a, b, c, d, in[0] + K1,  3);
77503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, d, a, b, c, in[1] + K1,  7);
78503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, c, d, a, b, in[2] + K1, 11);
79503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, b, c, d, a, in[3] + K1, 19);
80503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, a, b, c, d, in[4] + K1,  3);
81503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, d, a, b, c, in[5] + K1,  7);
82503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, c, d, a, b, in[6] + K1, 11);
83503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(F, b, c, d, a, in[7] + K1, 19);
84503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
85503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	/* Round 2 */
86503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, a, b, c, d, in[1] + K2,  3);
87503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, d, a, b, c, in[3] + K2,  5);
88503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, c, d, a, b, in[5] + K2,  9);
89503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, b, c, d, a, in[7] + K2, 13);
90503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, a, b, c, d, in[0] + K2,  3);
91503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, d, a, b, c, in[2] + K2,  5);
92503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, c, d, a, b, in[4] + K2,  9);
93503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(G, b, c, d, a, in[6] + K2, 13);
94503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
95503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	/* Round 3 */
96503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, a, b, c, d, in[3] + K3,  3);
97503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, d, a, b, c, in[7] + K3,  9);
98503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, c, d, a, b, in[2] + K3, 11);
99503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, b, c, d, a, in[6] + K3, 15);
100503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, a, b, c, d, in[1] + K3,  3);
101503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, d, a, b, c, in[5] + K3,  9);
102503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, c, d, a, b, in[0] + K3, 11);
103503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	ROUND(H, b, c, d, a, in[4] + K3, 15);
104503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
105503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	buf[0] += a;
106503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	buf[1] += b;
107503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	buf[2] += c;
108503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	buf[3] += d;
109503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o}
110503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
111503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef ROUND
112503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef F
113503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef G
114503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef H
115503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef K1
116503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef K2
117503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o#undef K3
118503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o
119503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o/* The old legacy hash */
120f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'ostatic ext2_dirhash_t dx_hack_hash (const char *name, int len,
121f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o				    int unsigned_flag)
12252783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o{
123f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	__u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
124f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	const unsigned char *ucp = (const unsigned char *) name;
125f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	const signed char *scp = (const signed char *) name;
126f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	int c;
127f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o
12852783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o	while (len--) {
129f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		if (unsigned_flag)
130f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			c = (int) *ucp++;
131f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		else
132f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			c = (int) *scp++;
133f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		hash = hash1 + (hash0 ^ (c * 7152373));
134efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
13552783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o		if (hash & 0x80000000) hash -= 0x7fffffff;
13652783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o		hash1 = hash0;
13752783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o		hash0 = hash;
13852783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o	}
1391acb01b4e28067a37c4f41e0a76df9f429fb417eTheodore Ts'o	return (hash0 << 1);
14052783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o}
14152783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o
142f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'ostatic void str2hashbuf(const char *msg, int len, __u32 *buf, int num,
143f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			int unsigned_flag)
144b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o{
145b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	__u32	pad, val;
146f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	int	i, c;
147f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	const unsigned char *ucp = (const unsigned char *) msg;
148f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	const signed char *scp = (const signed char *) msg;
149b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
150b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	pad = (__u32)len | ((__u32)len << 8);
151b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	pad |= pad << 16;
152b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
153b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	val = pad;
154b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	if (len > num*4)
155b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		len = num * 4;
156b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	for (i=0; i < len; i++) {
157b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		if ((i % 4) == 0)
158b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			val = pad;
159f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		if (unsigned_flag)
160f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			c = (int) ucp[i];
161f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		else
162f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			c = (int) scp[i];
163f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o
164f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		val = c + (val << 8);
165b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		if ((i % 4) == 3) {
166b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			*buf++ = val;
167b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			val = pad;
168b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			num--;
169b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		}
170b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	}
171b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	if (--num >= 0)
172b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		*buf++ = val;
173b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	while (--num >= 0)
174b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		*buf++ = pad;
175b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o}
176b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
17752783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o/*
17852783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * Returns the hash of a filename.  If len is 0 and name is NULL, then
17952783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * this function can be used to test whether or not a hash version is
18052783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o * supported.
181efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
182503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * The seed is an 4 longword (32 bits) "secret" which can be used to
183503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * uniquify a hash.  If the seed is all zero's, then some default seed
184503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * may be used.
185efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
186503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * A particular hash version specifies whether or not the seed is
187503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * represented, and whether or not the returned hash is 32 bits or 64
188503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o * bits.  32 bit hashes will return 0 for the minor hash.
18952783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o */
19052783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'oerrcode_t ext2fs_dirhash(int version, const char *name, int len,
191b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			 const __u32 *seed,
192503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o			 ext2_dirhash_t *ret_hash,
193503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o			 ext2_dirhash_t *ret_minor_hash)
19452783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o{
19552783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o	__u32	hash;
196503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	__u32	minor_hash = 0;
197cc90bdfd083036c9646f35ad6fa375af4ff92526Theodore Ts'o	const char	*p;
198b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	int		i;
199b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	__u32 		in[8], buf[4];
200f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	int		unsigned_flag = 0;
201b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o
202b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	/* Initialize the default seed for the hash checksum functions */
203b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	buf[0] = 0x67452301;
204b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	buf[1] = 0xefcdab89;
205b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	buf[2] = 0x98badcfe;
206b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	buf[3] = 0x10325476;
20752783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o
208503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	/* Check to see if the seed is all zero's */
209b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	if (seed) {
210b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		for (i=0; i < 4; i++) {
211b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			if (seed[i])
212b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o				break;
213b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		}
214b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		if (i < 4)
215b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			memcpy(buf, seed, sizeof(buf));
216503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	}
217efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
218b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	switch (version) {
219f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	case EXT2_HASH_LEGACY_UNSIGNED:
220f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		unsigned_flag++;
2219e30fb23ef85d6b2a58527048cc9208405a38299Eric Sandeen		/* fallthrough */
222b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	case EXT2_HASH_LEGACY:
223f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		hash = dx_hack_hash(name, len, unsigned_flag);
224b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		break;
225f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	case EXT2_HASH_HALF_MD4_UNSIGNED:
226f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		unsigned_flag++;
2279e30fb23ef85d6b2a58527048cc9208405a38299Eric Sandeen		/* fallthrough */
228b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	case EXT2_HASH_HALF_MD4:
229cc90bdfd083036c9646f35ad6fa375af4ff92526Theodore Ts'o		p = name;
230b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		while (len > 0) {
231f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			str2hashbuf(p, len, in, 8, unsigned_flag);
232b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			halfMD4Transform(buf, in);
233503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o			len -= 32;
234503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o			p += 32;
235503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o		}
236b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		minor_hash = buf[2];
237b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		hash = buf[1];
238b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		break;
239f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	case EXT2_HASH_TEA_UNSIGNED:
240f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o		unsigned_flag++;
2419e30fb23ef85d6b2a58527048cc9208405a38299Eric Sandeen		/* fallthrough */
242b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	case EXT2_HASH_TEA:
243b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		p = name;
244b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		while (len > 0) {
245f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o			str2hashbuf(p, len, in, 4, unsigned_flag);
246b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			TEA_transform(buf, in);
247b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			len -= 16;
248b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o			p += 16;
249b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		}
250b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		hash = buf[0];
251b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		minor_hash = buf[1];
252b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o		break;
253b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	default:
25452783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o		*ret_hash = 0;
25552783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o		return EXT2_ET_DIRHASH_UNSUPP;
25652783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o	}
257b33278c4d640c3fc8f99a314b637b7e502fceb9cTheodore Ts'o	*ret_hash = hash & ~1;
258503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o	if (ret_minor_hash)
259503f9e7f6eb331c5b75d7f1ad126f71bcdcfb4e3Theodore Ts'o		*ret_minor_hash = minor_hash;
26052783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o	return 0;
26152783e0ca72a80c549e9d266b3472f78fc61bdb2Theodore Ts'o}
262