1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * linux/fs/ext4/hash.c 4 * 5 * Copyright (C) 2002 by Theodore Ts'o 6 */ 7 8 #include <linux/fs.h> 9 #include <linux/compiler.h> 10 #include <linux/bitops.h> 11 #include "ext4.h" 12 13 #define DELTA 0x9E3779B9 14 15 static void TEA_transform(__u32 buf[4], __u32 const in[]) 16 { 17 __u32 sum = 0; 18 __u32 b0 = buf[0], b1 = buf[1]; 19 __u32 a = in[0], b = in[1], c = in[2], d = in[3]; 20 int n = 16; 21 22 do { 23 sum += DELTA; 24 b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); 25 b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); 26 } while (--n); 27 28 buf[0] += b0; 29 buf[1] += b1; 30 } 31 32 /* F, G and H are basic MD4 functions: selection, majority, parity */ 33 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 34 #define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) 35 #define H(x, y, z) ((x) ^ (y) ^ (z)) 36 37 /* 38 * The generic round function. The application is so specific that 39 * we don't bother protecting all the arguments with parens, as is generally 40 * good macro practice, in favor of extra legibility. 41 * Rotation is separate from addition to prevent recomputation 42 */ 43 #define ROUND(f, a, b, c, d, x, s) \ 44 (a += f(b, c, d) + x, a = rol32(a, s)) 45 #define K1 0 46 #define K2 013240474631UL 47 #define K3 015666365641UL 48 49 /* 50 * Basic cut-down MD4 transform. Returns only 32 bits of result. 51 */ 52 static __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]) 53 { 54 __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; 55 56 /* Round 1 */ 57 ROUND(F, a, b, c, d, in[0] + K1, 3); 58 ROUND(F, d, a, b, c, in[1] + K1, 7); 59 ROUND(F, c, d, a, b, in[2] + K1, 11); 60 ROUND(F, b, c, d, a, in[3] + K1, 19); 61 ROUND(F, a, b, c, d, in[4] + K1, 3); 62 ROUND(F, d, a, b, c, in[5] + K1, 7); 63 ROUND(F, c, d, a, b, in[6] + K1, 11); 64 ROUND(F, b, c, d, a, in[7] + K1, 19); 65 66 /* Round 2 */ 67 ROUND(G, a, b, c, d, in[1] + K2, 3); 68 ROUND(G, d, a, b, c, in[3] + K2, 5); 69 ROUND(G, c, d, a, b, in[5] + K2, 9); 70 ROUND(G, b, c, d, a, in[7] + K2, 13); 71 ROUND(G, a, b, c, d, in[0] + K2, 3); 72 ROUND(G, d, a, b, c, in[2] + K2, 5); 73 ROUND(G, c, d, a, b, in[4] + K2, 9); 74 ROUND(G, b, c, d, a, in[6] + K2, 13); 75 76 /* Round 3 */ 77 ROUND(H, a, b, c, d, in[3] + K3, 3); 78 ROUND(H, d, a, b, c, in[7] + K3, 9); 79 ROUND(H, c, d, a, b, in[2] + K3, 11); 80 ROUND(H, b, c, d, a, in[6] + K3, 15); 81 ROUND(H, a, b, c, d, in[1] + K3, 3); 82 ROUND(H, d, a, b, c, in[5] + K3, 9); 83 ROUND(H, c, d, a, b, in[0] + K3, 11); 84 ROUND(H, b, c, d, a, in[4] + K3, 15); 85 86 buf[0] += a; 87 buf[1] += b; 88 buf[2] += c; 89 buf[3] += d; 90 91 return buf[1]; /* "most hashed" word */ 92 } 93 #undef ROUND 94 #undef K1 95 #undef K2 96 #undef K3 97 #undef F 98 #undef G 99 #undef H 100 101 /* The old legacy hash */ 102 static __u32 dx_hack_hash_unsigned(const char *name, int len) 103 { 104 __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; 105 const unsigned char *ucp = (const unsigned char *) name; 106 107 while (len--) { 108 hash = hash1 + (hash0 ^ (((int) *ucp++) * 7152373)); 109 110 if (hash & 0x80000000) 111 hash -= 0x7fffffff; 112 hash1 = hash0; 113 hash0 = hash; 114 } 115 return hash0 << 1; 116 } 117 118 static __u32 dx_hack_hash_signed(const char *name, int len) 119 { 120 __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; 121 const signed char *scp = (const signed char *) name; 122 123 while (len--) { 124 hash = hash1 + (hash0 ^ (((int) *scp++) * 7152373)); 125 126 if (hash & 0x80000000) 127 hash -= 0x7fffffff; 128 hash1 = hash0; 129 hash0 = hash; 130 } 131 return hash0 << 1; 132 } 133 134 static void str2hashbuf_signed(const char *msg, int len, __u32 *buf, int num) 135 { 136 __u32 pad, val; 137 int i; 138 const signed char *scp = (const signed char *) msg; 139 140 pad = (__u32)len | ((__u32)len << 8); 141 pad |= pad << 16; 142 143 val = pad; 144 if (len > num*4) 145 len = num * 4; 146 for (i = 0; i < len; i++) { 147 val = ((int) scp[i]) + (val << 8); 148 if ((i % 4) == 3) { 149 *buf++ = val; 150 val = pad; 151 num--; 152 } 153 } 154 if (--num >= 0) 155 *buf++ = val; 156 while (--num >= 0) 157 *buf++ = pad; 158 } 159 160 static void str2hashbuf_unsigned(const char *msg, int len, __u32 *buf, int num) 161 { 162 __u32 pad, val; 163 int i; 164 const unsigned char *ucp = (const unsigned char *) msg; 165 166 pad = (__u32)len | ((__u32)len << 8); 167 pad |= pad << 16; 168 169 val = pad; 170 if (len > num*4) 171 len = num * 4; 172 for (i = 0; i < len; i++) { 173 val = ((int) ucp[i]) + (val << 8); 174 if ((i % 4) == 3) { 175 *buf++ = val; 176 val = pad; 177 num--; 178 } 179 } 180 if (--num >= 0) 181 *buf++ = val; 182 while (--num >= 0) 183 *buf++ = pad; 184 } 185 186 /* 187 * Returns the hash of a filename. If len is 0 and name is NULL, then 188 * this function can be used to test whether or not a hash version is 189 * supported. 190 * 191 * The seed is an 4 longword (32 bits) "secret" which can be used to 192 * uniquify a hash. If the seed is all zero's, then some default seed 193 * may be used. 194 * 195 * A particular hash version specifies whether or not the seed is 196 * represented, and whether or not the returned hash is 32 bits or 64 197 * bits. 32 bit hashes will return 0 for the minor hash. 198 */ 199 int ext4fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) 200 { 201 __u32 hash; 202 __u32 minor_hash = 0; 203 const char *p; 204 int i; 205 __u32 in[8], buf[4]; 206 void (*str2hashbuf)(const char *, int, __u32 *, int) = 207 str2hashbuf_signed; 208 209 /* Initialize the default seed for the hash checksum functions */ 210 buf[0] = 0x67452301; 211 buf[1] = 0xefcdab89; 212 buf[2] = 0x98badcfe; 213 buf[3] = 0x10325476; 214 215 /* Check to see if the seed is all zero's */ 216 if (hinfo->seed) { 217 for (i = 0; i < 4; i++) { 218 if (hinfo->seed[i]) { 219 memcpy(buf, hinfo->seed, sizeof(buf)); 220 break; 221 } 222 } 223 } 224 225 switch (hinfo->hash_version) { 226 case DX_HASH_LEGACY_UNSIGNED: 227 hash = dx_hack_hash_unsigned(name, len); 228 break; 229 case DX_HASH_LEGACY: 230 hash = dx_hack_hash_signed(name, len); 231 break; 232 case DX_HASH_HALF_MD4_UNSIGNED: 233 str2hashbuf = str2hashbuf_unsigned; 234 case DX_HASH_HALF_MD4: 235 p = name; 236 while (len > 0) { 237 (*str2hashbuf)(p, len, in, 8); 238 half_md4_transform(buf, in); 239 len -= 32; 240 p += 32; 241 } 242 minor_hash = buf[2]; 243 hash = buf[1]; 244 break; 245 case DX_HASH_TEA_UNSIGNED: 246 str2hashbuf = str2hashbuf_unsigned; 247 case DX_HASH_TEA: 248 p = name; 249 while (len > 0) { 250 (*str2hashbuf)(p, len, in, 4); 251 TEA_transform(buf, in); 252 len -= 16; 253 p += 16; 254 } 255 hash = buf[0]; 256 minor_hash = buf[1]; 257 break; 258 default: 259 hinfo->hash = 0; 260 return -1; 261 } 262 hash = hash & ~1; 263 if (hash == (EXT4_HTREE_EOF_32BIT << 1)) 264 hash = (EXT4_HTREE_EOF_32BIT - 1) << 1; 265 hinfo->hash = hash; 266 hinfo->minor_hash = minor_hash; 267 return 0; 268 } 269