xref: /aosp_15_r20/external/e2fsprogs/lib/ext2fs/dirhash.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker  * dirhash.c -- Calculate the hash of a directory entry
3*6a54128fSAndroid Build Coastguard Worker  *
4*6a54128fSAndroid Build Coastguard Worker  * Copyright (c) 2001  Daniel Phillips
5*6a54128fSAndroid Build Coastguard Worker  *
6*6a54128fSAndroid Build Coastguard Worker  * Copyright (c) 2002 Theodore Ts'o.
7*6a54128fSAndroid Build Coastguard Worker  *
8*6a54128fSAndroid Build Coastguard Worker  * %Begin-Header%
9*6a54128fSAndroid Build Coastguard Worker  * This file may be redistributed under the terms of the GNU Library
10*6a54128fSAndroid Build Coastguard Worker  * General Public License, version 2.
11*6a54128fSAndroid Build Coastguard Worker  * %End-Header%
12*6a54128fSAndroid Build Coastguard Worker  */
13*6a54128fSAndroid Build Coastguard Worker 
14*6a54128fSAndroid Build Coastguard Worker #include "config.h"
15*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
16*6a54128fSAndroid Build Coastguard Worker #include <string.h>
17*6a54128fSAndroid Build Coastguard Worker #include <limits.h>
18*6a54128fSAndroid Build Coastguard Worker 
19*6a54128fSAndroid Build Coastguard Worker #include "ext2_fs.h"
20*6a54128fSAndroid Build Coastguard Worker #include "ext2fs.h"
21*6a54128fSAndroid Build Coastguard Worker #include "ext2fsP.h"
22*6a54128fSAndroid Build Coastguard Worker 
23*6a54128fSAndroid Build Coastguard Worker #ifndef PATH_MAX
24*6a54128fSAndroid Build Coastguard Worker #define PATH_MAX 4096
25*6a54128fSAndroid Build Coastguard Worker #endif
26*6a54128fSAndroid Build Coastguard Worker 
27*6a54128fSAndroid Build Coastguard Worker /*
28*6a54128fSAndroid Build Coastguard Worker  * Keyed 32-bit hash function using TEA in a Davis-Meyer function
29*6a54128fSAndroid Build Coastguard Worker  *   H0 = Key
30*6a54128fSAndroid Build Coastguard Worker  *   Hi = E Mi(Hi-1) + Hi-1
31*6a54128fSAndroid Build Coastguard Worker  *
32*6a54128fSAndroid Build Coastguard Worker  * (see Applied Cryptography, 2nd edition, p448).
33*6a54128fSAndroid Build Coastguard Worker  *
34*6a54128fSAndroid Build Coastguard Worker  * Jeremy Fitzhardinge <[email protected]> 1998
35*6a54128fSAndroid Build Coastguard Worker  *
36*6a54128fSAndroid Build Coastguard Worker  * This code is made available under the terms of the GPL
37*6a54128fSAndroid Build Coastguard Worker  */
38*6a54128fSAndroid Build Coastguard Worker #define DELTA 0x9E3779B9
39*6a54128fSAndroid Build Coastguard Worker 
TEA_transform(__u32 buf[4],__u32 const in[])40*6a54128fSAndroid Build Coastguard Worker static void TEA_transform(__u32 buf[4], __u32 const in[])
41*6a54128fSAndroid Build Coastguard Worker {
42*6a54128fSAndroid Build Coastguard Worker 	__u32	sum = 0;
43*6a54128fSAndroid Build Coastguard Worker 	__u32	b0 = buf[0], b1 = buf[1];
44*6a54128fSAndroid Build Coastguard Worker 	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
45*6a54128fSAndroid Build Coastguard Worker 	int	n = 16;
46*6a54128fSAndroid Build Coastguard Worker 
47*6a54128fSAndroid Build Coastguard Worker 	do {
48*6a54128fSAndroid Build Coastguard Worker 		sum += DELTA;
49*6a54128fSAndroid Build Coastguard Worker 		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
50*6a54128fSAndroid Build Coastguard Worker 		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
51*6a54128fSAndroid Build Coastguard Worker 	} while(--n);
52*6a54128fSAndroid Build Coastguard Worker 
53*6a54128fSAndroid Build Coastguard Worker 	buf[0] += b0;
54*6a54128fSAndroid Build Coastguard Worker 	buf[1] += b1;
55*6a54128fSAndroid Build Coastguard Worker }
56*6a54128fSAndroid Build Coastguard Worker 
57*6a54128fSAndroid Build Coastguard Worker /* F, G and H are basic MD4 functions: selection, majority, parity */
58*6a54128fSAndroid Build Coastguard Worker #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
59*6a54128fSAndroid Build Coastguard Worker #define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
60*6a54128fSAndroid Build Coastguard Worker #define H(x, y, z) ((x) ^ (y) ^ (z))
61*6a54128fSAndroid Build Coastguard Worker 
62*6a54128fSAndroid Build Coastguard Worker /*
63*6a54128fSAndroid Build Coastguard Worker  * The generic round function.  The application is so specific that
64*6a54128fSAndroid Build Coastguard Worker  * we don't bother protecting all the arguments with parens, as is generally
65*6a54128fSAndroid Build Coastguard Worker  * good macro practice, in favor of extra legibility.
66*6a54128fSAndroid Build Coastguard Worker  * Rotation is separate from addition to prevent recomputation
67*6a54128fSAndroid Build Coastguard Worker  */
68*6a54128fSAndroid Build Coastguard Worker #define ROUND(f, a, b, c, d, x, s)	\
69*6a54128fSAndroid Build Coastguard Worker 	(a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
70*6a54128fSAndroid Build Coastguard Worker #define K1 0
71*6a54128fSAndroid Build Coastguard Worker #define K2 013240474631UL
72*6a54128fSAndroid Build Coastguard Worker #define K3 015666365641UL
73*6a54128fSAndroid Build Coastguard Worker 
74*6a54128fSAndroid Build Coastguard Worker /*
75*6a54128fSAndroid Build Coastguard Worker  * Basic cut-down MD4 transform.  Returns only 32 bits of result.
76*6a54128fSAndroid Build Coastguard Worker  */
halfMD4Transform(__u32 buf[4],__u32 const in[])77*6a54128fSAndroid Build Coastguard Worker static void halfMD4Transform (__u32 buf[4], __u32 const in[])
78*6a54128fSAndroid Build Coastguard Worker {
79*6a54128fSAndroid Build Coastguard Worker 	__u32	a = buf[0], b = buf[1], c = buf[2], d = buf[3];
80*6a54128fSAndroid Build Coastguard Worker 
81*6a54128fSAndroid Build Coastguard Worker 	/* Round 1 */
82*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, a, b, c, d, in[0] + K1,  3);
83*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, d, a, b, c, in[1] + K1,  7);
84*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, c, d, a, b, in[2] + K1, 11);
85*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, b, c, d, a, in[3] + K1, 19);
86*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, a, b, c, d, in[4] + K1,  3);
87*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, d, a, b, c, in[5] + K1,  7);
88*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, c, d, a, b, in[6] + K1, 11);
89*6a54128fSAndroid Build Coastguard Worker 	ROUND(F, b, c, d, a, in[7] + K1, 19);
90*6a54128fSAndroid Build Coastguard Worker 
91*6a54128fSAndroid Build Coastguard Worker 	/* Round 2 */
92*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, a, b, c, d, in[1] + K2,  3);
93*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, d, a, b, c, in[3] + K2,  5);
94*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, c, d, a, b, in[5] + K2,  9);
95*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, b, c, d, a, in[7] + K2, 13);
96*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, a, b, c, d, in[0] + K2,  3);
97*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, d, a, b, c, in[2] + K2,  5);
98*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, c, d, a, b, in[4] + K2,  9);
99*6a54128fSAndroid Build Coastguard Worker 	ROUND(G, b, c, d, a, in[6] + K2, 13);
100*6a54128fSAndroid Build Coastguard Worker 
101*6a54128fSAndroid Build Coastguard Worker 	/* Round 3 */
102*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, a, b, c, d, in[3] + K3,  3);
103*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, d, a, b, c, in[7] + K3,  9);
104*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, c, d, a, b, in[2] + K3, 11);
105*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, b, c, d, a, in[6] + K3, 15);
106*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, a, b, c, d, in[1] + K3,  3);
107*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, d, a, b, c, in[5] + K3,  9);
108*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, c, d, a, b, in[0] + K3, 11);
109*6a54128fSAndroid Build Coastguard Worker 	ROUND(H, b, c, d, a, in[4] + K3, 15);
110*6a54128fSAndroid Build Coastguard Worker 
111*6a54128fSAndroid Build Coastguard Worker 	buf[0] += a;
112*6a54128fSAndroid Build Coastguard Worker 	buf[1] += b;
113*6a54128fSAndroid Build Coastguard Worker 	buf[2] += c;
114*6a54128fSAndroid Build Coastguard Worker 	buf[3] += d;
115*6a54128fSAndroid Build Coastguard Worker }
116*6a54128fSAndroid Build Coastguard Worker 
117*6a54128fSAndroid Build Coastguard Worker #undef ROUND
118*6a54128fSAndroid Build Coastguard Worker #undef F
119*6a54128fSAndroid Build Coastguard Worker #undef G
120*6a54128fSAndroid Build Coastguard Worker #undef H
121*6a54128fSAndroid Build Coastguard Worker #undef K1
122*6a54128fSAndroid Build Coastguard Worker #undef K2
123*6a54128fSAndroid Build Coastguard Worker #undef K3
124*6a54128fSAndroid Build Coastguard Worker 
125*6a54128fSAndroid Build Coastguard Worker /* The old legacy hash */
dx_hack_hash(const char * name,int len,int unsigned_flag)126*6a54128fSAndroid Build Coastguard Worker static ext2_dirhash_t dx_hack_hash (const char *name, int len,
127*6a54128fSAndroid Build Coastguard Worker 				    int unsigned_flag)
128*6a54128fSAndroid Build Coastguard Worker {
129*6a54128fSAndroid Build Coastguard Worker 	__u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
130*6a54128fSAndroid Build Coastguard Worker 	const unsigned char *ucp = (const unsigned char *) name;
131*6a54128fSAndroid Build Coastguard Worker 	const signed char *scp = (const signed char *) name;
132*6a54128fSAndroid Build Coastguard Worker 	int c;
133*6a54128fSAndroid Build Coastguard Worker 
134*6a54128fSAndroid Build Coastguard Worker 	while (len--) {
135*6a54128fSAndroid Build Coastguard Worker 		if (unsigned_flag)
136*6a54128fSAndroid Build Coastguard Worker 			c = (int) *ucp++;
137*6a54128fSAndroid Build Coastguard Worker 		else
138*6a54128fSAndroid Build Coastguard Worker 			c = (int) *scp++;
139*6a54128fSAndroid Build Coastguard Worker 		hash = hash1 + (hash0 ^ (c * 7152373));
140*6a54128fSAndroid Build Coastguard Worker 
141*6a54128fSAndroid Build Coastguard Worker 		if (hash & 0x80000000) hash -= 0x7fffffff;
142*6a54128fSAndroid Build Coastguard Worker 		hash1 = hash0;
143*6a54128fSAndroid Build Coastguard Worker 		hash0 = hash;
144*6a54128fSAndroid Build Coastguard Worker 	}
145*6a54128fSAndroid Build Coastguard Worker 	return (hash0 << 1);
146*6a54128fSAndroid Build Coastguard Worker }
147*6a54128fSAndroid Build Coastguard Worker 
str2hashbuf(const char * msg,int len,__u32 * buf,int num,int unsigned_flag)148*6a54128fSAndroid Build Coastguard Worker static void str2hashbuf(const char *msg, int len, __u32 *buf, int num,
149*6a54128fSAndroid Build Coastguard Worker 			int unsigned_flag)
150*6a54128fSAndroid Build Coastguard Worker {
151*6a54128fSAndroid Build Coastguard Worker 	__u32	pad, val;
152*6a54128fSAndroid Build Coastguard Worker 	int	i, c;
153*6a54128fSAndroid Build Coastguard Worker 	const unsigned char *ucp = (const unsigned char *) msg;
154*6a54128fSAndroid Build Coastguard Worker 	const signed char *scp = (const signed char *) msg;
155*6a54128fSAndroid Build Coastguard Worker 
156*6a54128fSAndroid Build Coastguard Worker 	pad = (__u32)len | ((__u32)len << 8);
157*6a54128fSAndroid Build Coastguard Worker 	pad |= pad << 16;
158*6a54128fSAndroid Build Coastguard Worker 
159*6a54128fSAndroid Build Coastguard Worker 	val = pad;
160*6a54128fSAndroid Build Coastguard Worker 	if (len > num*4)
161*6a54128fSAndroid Build Coastguard Worker 		len = num * 4;
162*6a54128fSAndroid Build Coastguard Worker 	for (i=0; i < len; i++) {
163*6a54128fSAndroid Build Coastguard Worker 		if (unsigned_flag)
164*6a54128fSAndroid Build Coastguard Worker 			c = (int) ucp[i];
165*6a54128fSAndroid Build Coastguard Worker 		else
166*6a54128fSAndroid Build Coastguard Worker 			c = (int) scp[i];
167*6a54128fSAndroid Build Coastguard Worker 
168*6a54128fSAndroid Build Coastguard Worker 		val = c + (val << 8);
169*6a54128fSAndroid Build Coastguard Worker 		if ((i % 4) == 3) {
170*6a54128fSAndroid Build Coastguard Worker 			*buf++ = val;
171*6a54128fSAndroid Build Coastguard Worker 			val = pad;
172*6a54128fSAndroid Build Coastguard Worker 			num--;
173*6a54128fSAndroid Build Coastguard Worker 		}
174*6a54128fSAndroid Build Coastguard Worker 	}
175*6a54128fSAndroid Build Coastguard Worker 	if (--num >= 0)
176*6a54128fSAndroid Build Coastguard Worker 		*buf++ = val;
177*6a54128fSAndroid Build Coastguard Worker 	while (--num >= 0)
178*6a54128fSAndroid Build Coastguard Worker 		*buf++ = pad;
179*6a54128fSAndroid Build Coastguard Worker }
180*6a54128fSAndroid Build Coastguard Worker 
181*6a54128fSAndroid Build Coastguard Worker /*
182*6a54128fSAndroid Build Coastguard Worker  * Returns the hash of a filename.  If len is 0 and name is NULL, then
183*6a54128fSAndroid Build Coastguard Worker  * this function can be used to test whether or not a hash version is
184*6a54128fSAndroid Build Coastguard Worker  * supported.
185*6a54128fSAndroid Build Coastguard Worker  *
186*6a54128fSAndroid Build Coastguard Worker  * The seed is an 4 longword (32 bits) "secret" which can be used to
187*6a54128fSAndroid Build Coastguard Worker  * uniquify a hash.  If the seed is all zero's, then some default seed
188*6a54128fSAndroid Build Coastguard Worker  * may be used.
189*6a54128fSAndroid Build Coastguard Worker  *
190*6a54128fSAndroid Build Coastguard Worker  * A particular hash version specifies whether or not the seed is
191*6a54128fSAndroid Build Coastguard Worker  * represented, and whether or not the returned hash is 32 bits or 64
192*6a54128fSAndroid Build Coastguard Worker  * bits.  32 bit hashes will return 0 for the minor hash.
193*6a54128fSAndroid Build Coastguard Worker  *
194*6a54128fSAndroid Build Coastguard Worker  * This function doesn't do any normalization or casefolding of the
195*6a54128fSAndroid Build Coastguard Worker  * input string.  To take charset encoding into account, use
196*6a54128fSAndroid Build Coastguard Worker  * ext2fs_dirhash2.
197*6a54128fSAndroid Build Coastguard Worker  *
198*6a54128fSAndroid Build Coastguard Worker  */
ext2fs_dirhash(int version,const char * name,int len,const __u32 * seed,ext2_dirhash_t * ret_hash,ext2_dirhash_t * ret_minor_hash)199*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_dirhash(int version, const char *name, int len,
200*6a54128fSAndroid Build Coastguard Worker 			 const __u32 *seed,
201*6a54128fSAndroid Build Coastguard Worker 			 ext2_dirhash_t *ret_hash,
202*6a54128fSAndroid Build Coastguard Worker 			 ext2_dirhash_t *ret_minor_hash)
203*6a54128fSAndroid Build Coastguard Worker {
204*6a54128fSAndroid Build Coastguard Worker 	__u32	hash;
205*6a54128fSAndroid Build Coastguard Worker 	__u32	minor_hash = 0;
206*6a54128fSAndroid Build Coastguard Worker 	const char	*p;
207*6a54128fSAndroid Build Coastguard Worker 	int		i;
208*6a54128fSAndroid Build Coastguard Worker 	__u32 		in[8], buf[4];
209*6a54128fSAndroid Build Coastguard Worker 	int		unsigned_flag = 0;
210*6a54128fSAndroid Build Coastguard Worker 
211*6a54128fSAndroid Build Coastguard Worker 	/* Initialize the default seed for the hash checksum functions */
212*6a54128fSAndroid Build Coastguard Worker 	buf[0] = 0x67452301;
213*6a54128fSAndroid Build Coastguard Worker 	buf[1] = 0xefcdab89;
214*6a54128fSAndroid Build Coastguard Worker 	buf[2] = 0x98badcfe;
215*6a54128fSAndroid Build Coastguard Worker 	buf[3] = 0x10325476;
216*6a54128fSAndroid Build Coastguard Worker 
217*6a54128fSAndroid Build Coastguard Worker 	/* Check to see if the seed is all zero's */
218*6a54128fSAndroid Build Coastguard Worker 	if (seed) {
219*6a54128fSAndroid Build Coastguard Worker 		for (i=0; i < 4; i++) {
220*6a54128fSAndroid Build Coastguard Worker 			if (seed[i])
221*6a54128fSAndroid Build Coastguard Worker 				break;
222*6a54128fSAndroid Build Coastguard Worker 		}
223*6a54128fSAndroid Build Coastguard Worker 		if (i < 4)
224*6a54128fSAndroid Build Coastguard Worker 			memcpy(buf, seed, sizeof(buf));
225*6a54128fSAndroid Build Coastguard Worker 	}
226*6a54128fSAndroid Build Coastguard Worker 
227*6a54128fSAndroid Build Coastguard Worker 	switch (version) {
228*6a54128fSAndroid Build Coastguard Worker 	case EXT2_HASH_LEGACY_UNSIGNED:
229*6a54128fSAndroid Build Coastguard Worker 		unsigned_flag++;
230*6a54128fSAndroid Build Coastguard Worker 		/* fallthrough */
231*6a54128fSAndroid Build Coastguard Worker 	case EXT2_HASH_LEGACY:
232*6a54128fSAndroid Build Coastguard Worker 		hash = dx_hack_hash(name, len, unsigned_flag);
233*6a54128fSAndroid Build Coastguard Worker 		break;
234*6a54128fSAndroid Build Coastguard Worker 	case EXT2_HASH_HALF_MD4_UNSIGNED:
235*6a54128fSAndroid Build Coastguard Worker 		unsigned_flag++;
236*6a54128fSAndroid Build Coastguard Worker 		/* fallthrough */
237*6a54128fSAndroid Build Coastguard Worker 	case EXT2_HASH_HALF_MD4:
238*6a54128fSAndroid Build Coastguard Worker 		p = name;
239*6a54128fSAndroid Build Coastguard Worker 		while (len > 0) {
240*6a54128fSAndroid Build Coastguard Worker 			str2hashbuf(p, len, in, 8, unsigned_flag);
241*6a54128fSAndroid Build Coastguard Worker 			halfMD4Transform(buf, in);
242*6a54128fSAndroid Build Coastguard Worker 			len -= 32;
243*6a54128fSAndroid Build Coastguard Worker 			p += 32;
244*6a54128fSAndroid Build Coastguard Worker 		}
245*6a54128fSAndroid Build Coastguard Worker 		minor_hash = buf[2];
246*6a54128fSAndroid Build Coastguard Worker 		hash = buf[1];
247*6a54128fSAndroid Build Coastguard Worker 		break;
248*6a54128fSAndroid Build Coastguard Worker 	case EXT2_HASH_TEA_UNSIGNED:
249*6a54128fSAndroid Build Coastguard Worker 		unsigned_flag++;
250*6a54128fSAndroid Build Coastguard Worker 		/* fallthrough */
251*6a54128fSAndroid Build Coastguard Worker 	case EXT2_HASH_TEA:
252*6a54128fSAndroid Build Coastguard Worker 		p = name;
253*6a54128fSAndroid Build Coastguard Worker 		while (len > 0) {
254*6a54128fSAndroid Build Coastguard Worker 			str2hashbuf(p, len, in, 4, unsigned_flag);
255*6a54128fSAndroid Build Coastguard Worker 			TEA_transform(buf, in);
256*6a54128fSAndroid Build Coastguard Worker 			len -= 16;
257*6a54128fSAndroid Build Coastguard Worker 			p += 16;
258*6a54128fSAndroid Build Coastguard Worker 		}
259*6a54128fSAndroid Build Coastguard Worker 		hash = buf[0];
260*6a54128fSAndroid Build Coastguard Worker 		minor_hash = buf[1];
261*6a54128fSAndroid Build Coastguard Worker 		break;
262*6a54128fSAndroid Build Coastguard Worker 	default:
263*6a54128fSAndroid Build Coastguard Worker 		*ret_hash = 0;
264*6a54128fSAndroid Build Coastguard Worker 		return EXT2_ET_DIRHASH_UNSUPP;
265*6a54128fSAndroid Build Coastguard Worker 	}
266*6a54128fSAndroid Build Coastguard Worker 	*ret_hash = hash & ~1;
267*6a54128fSAndroid Build Coastguard Worker 	if (ret_minor_hash)
268*6a54128fSAndroid Build Coastguard Worker 		*ret_minor_hash = minor_hash;
269*6a54128fSAndroid Build Coastguard Worker 	return 0;
270*6a54128fSAndroid Build Coastguard Worker }
271*6a54128fSAndroid Build Coastguard Worker 
272*6a54128fSAndroid Build Coastguard Worker /*
273*6a54128fSAndroid Build Coastguard Worker  * Returns the hash of a filename considering normalization and
274*6a54128fSAndroid Build Coastguard Worker  * casefolding.  This is a wrapper around ext2fs_dirhash with string
275*6a54128fSAndroid Build Coastguard Worker  * encoding support based on the nls_table and the flags. Check
276*6a54128fSAndroid Build Coastguard Worker  * ext2fs_dirhash for documentation on the input and output parameters.
277*6a54128fSAndroid Build Coastguard Worker  */
ext2fs_dirhash2(int version,const char * name,int len,const struct ext2fs_nls_table * charset,int hash_flags,const __u32 * seed,ext2_dirhash_t * ret_hash,ext2_dirhash_t * ret_minor_hash)278*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_dirhash2(int version, const char *name, int len,
279*6a54128fSAndroid Build Coastguard Worker 			  const struct ext2fs_nls_table *charset,
280*6a54128fSAndroid Build Coastguard Worker 			  int hash_flags, const __u32 *seed,
281*6a54128fSAndroid Build Coastguard Worker 			  ext2_dirhash_t *ret_hash,
282*6a54128fSAndroid Build Coastguard Worker 			  ext2_dirhash_t *ret_minor_hash)
283*6a54128fSAndroid Build Coastguard Worker {
284*6a54128fSAndroid Build Coastguard Worker 	errcode_t r;
285*6a54128fSAndroid Build Coastguard Worker 	int dlen;
286*6a54128fSAndroid Build Coastguard Worker 
287*6a54128fSAndroid Build Coastguard Worker 	if (len && charset && (hash_flags & EXT4_CASEFOLD_FL)) {
288*6a54128fSAndroid Build Coastguard Worker 		char buff[PATH_MAX];
289*6a54128fSAndroid Build Coastguard Worker 
290*6a54128fSAndroid Build Coastguard Worker 		dlen = charset->ops->casefold(charset,
291*6a54128fSAndroid Build Coastguard Worker 			      (const unsigned char *) name, len,
292*6a54128fSAndroid Build Coastguard Worker 			      (unsigned char *) buff, sizeof(buff));
293*6a54128fSAndroid Build Coastguard Worker 		if (dlen < 0) {
294*6a54128fSAndroid Build Coastguard Worker 			if (dlen == -EINVAL)
295*6a54128fSAndroid Build Coastguard Worker 				goto opaque_seq;
296*6a54128fSAndroid Build Coastguard Worker 
297*6a54128fSAndroid Build Coastguard Worker 			return dlen;
298*6a54128fSAndroid Build Coastguard Worker 		}
299*6a54128fSAndroid Build Coastguard Worker 		r = ext2fs_dirhash(version, buff, dlen, seed, ret_hash,
300*6a54128fSAndroid Build Coastguard Worker 				   ret_minor_hash);
301*6a54128fSAndroid Build Coastguard Worker 		return r;
302*6a54128fSAndroid Build Coastguard Worker 	}
303*6a54128fSAndroid Build Coastguard Worker 
304*6a54128fSAndroid Build Coastguard Worker opaque_seq:
305*6a54128fSAndroid Build Coastguard Worker 	return ext2fs_dirhash(version, name, len, seed, ret_hash,
306*6a54128fSAndroid Build Coastguard Worker 			      ret_minor_hash);
307*6a54128fSAndroid Build Coastguard Worker }
308