dirhash.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * dirhash.c -- Calculate the hash of a directory entry
  3. *
  4. * Copyright (c) 2001 Daniel Phillips
  5. *
  6. * Copyright (c) 2002 Theodore Ts'o.
  7. *
  8. * %Begin-Header%
  9. * This file may be redistributed under the terms of the GNU Public
  10. * License.
  11. * %End-Header%
  12. */
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include "ext2_fs.h"
  16. #include "ext2fs.h"
  17. /*
  18. * Keyed 32-bit hash function using TEA in a Davis-Meyer function
  19. * H0 = Key
  20. * Hi = E Mi(Hi-1) + Hi-1
  21. *
  22. * (see Applied Cryptography, 2nd edition, p448).
  23. *
  24. * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
  25. *
  26. * This code is made available under the terms of the GPL
  27. */
  28. #define DELTA 0x9E3779B9
  29. static void TEA_transform(__u32 buf[4], __u32 const in[])
  30. {
  31. __u32 sum = 0;
  32. __u32 b0 = buf[0], b1 = buf[1];
  33. __u32 a = in[0], b = in[1], c = in[2], d = in[3];
  34. int n = 16;
  35. do {
  36. sum += DELTA;
  37. b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
  38. b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
  39. } while(--n);
  40. buf[0] += b0;
  41. buf[1] += b1;
  42. }
  43. /* F, G and H are basic MD4 functions: selection, majority, parity */
  44. #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
  45. #define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
  46. #define H(x, y, z) ((x) ^ (y) ^ (z))
  47. /*
  48. * The generic round function. The application is so specific that
  49. * we don't bother protecting all the arguments with parens, as is generally
  50. * good macro practice, in favor of extra legibility.
  51. * Rotation is separate from addition to prevent recomputation
  52. */
  53. #define ROUND(f, a, b, c, d, x, s) \
  54. (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
  55. #define K1 0
  56. #define K2 013240474631UL
  57. #define K3 015666365641UL
  58. /*
  59. * Basic cut-down MD4 transform. Returns only 32 bits of result.
  60. */
  61. static void halfMD4Transform (__u32 buf[4], __u32 const in[])
  62. {
  63. __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
  64. /* Round 1 */
  65. ROUND(F, a, b, c, d, in[0] + K1, 3);
  66. ROUND(F, d, a, b, c, in[1] + K1, 7);
  67. ROUND(F, c, d, a, b, in[2] + K1, 11);
  68. ROUND(F, b, c, d, a, in[3] + K1, 19);
  69. ROUND(F, a, b, c, d, in[4] + K1, 3);
  70. ROUND(F, d, a, b, c, in[5] + K1, 7);
  71. ROUND(F, c, d, a, b, in[6] + K1, 11);
  72. ROUND(F, b, c, d, a, in[7] + K1, 19);
  73. /* Round 2 */
  74. ROUND(G, a, b, c, d, in[1] + K2, 3);
  75. ROUND(G, d, a, b, c, in[3] + K2, 5);
  76. ROUND(G, c, d, a, b, in[5] + K2, 9);
  77. ROUND(G, b, c, d, a, in[7] + K2, 13);
  78. ROUND(G, a, b, c, d, in[0] + K2, 3);
  79. ROUND(G, d, a, b, c, in[2] + K2, 5);
  80. ROUND(G, c, d, a, b, in[4] + K2, 9);
  81. ROUND(G, b, c, d, a, in[6] + K2, 13);
  82. /* Round 3 */
  83. ROUND(H, a, b, c, d, in[3] + K3, 3);
  84. ROUND(H, d, a, b, c, in[7] + K3, 9);
  85. ROUND(H, c, d, a, b, in[2] + K3, 11);
  86. ROUND(H, b, c, d, a, in[6] + K3, 15);
  87. ROUND(H, a, b, c, d, in[1] + K3, 3);
  88. ROUND(H, d, a, b, c, in[5] + K3, 9);
  89. ROUND(H, c, d, a, b, in[0] + K3, 11);
  90. ROUND(H, b, c, d, a, in[4] + K3, 15);
  91. buf[0] += a;
  92. buf[1] += b;
  93. buf[2] += c;
  94. buf[3] += d;
  95. }
  96. #undef ROUND
  97. #undef F
  98. #undef G
  99. #undef H
  100. #undef K1
  101. #undef K2
  102. #undef K3
  103. /* The old legacy hash */
  104. static ext2_dirhash_t dx_hack_hash (const char *name, int len)
  105. {
  106. __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
  107. while (len--) {
  108. __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
  109. if (hash & 0x80000000) hash -= 0x7fffffff;
  110. hash1 = hash0;
  111. hash0 = hash;
  112. }
  113. return (hash0 << 1);
  114. }
  115. static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
  116. {
  117. __u32 pad, val;
  118. int i;
  119. pad = (__u32)len | ((__u32)len << 8);
  120. pad |= pad << 16;
  121. val = pad;
  122. if (len > num*4)
  123. len = num * 4;
  124. for (i=0; i < len; i++) {
  125. if ((i % 4) == 0)
  126. val = pad;
  127. val = msg[i] + (val << 8);
  128. if ((i % 4) == 3) {
  129. *buf++ = val;
  130. val = pad;
  131. num--;
  132. }
  133. }
  134. if (--num >= 0)
  135. *buf++ = val;
  136. while (--num >= 0)
  137. *buf++ = pad;
  138. }
  139. /*
  140. * Returns the hash of a filename. If len is 0 and name is NULL, then
  141. * this function can be used to test whether or not a hash version is
  142. * supported.
  143. *
  144. * The seed is an 4 longword (32 bits) "secret" which can be used to
  145. * uniquify a hash. If the seed is all zero's, then some default seed
  146. * may be used.
  147. *
  148. * A particular hash version specifies whether or not the seed is
  149. * represented, and whether or not the returned hash is 32 bits or 64
  150. * bits. 32 bit hashes will return 0 for the minor hash.
  151. */
  152. errcode_t ext2fs_dirhash(int version, const char *name, int len,
  153. const __u32 *seed,
  154. ext2_dirhash_t *ret_hash,
  155. ext2_dirhash_t *ret_minor_hash)
  156. {
  157. __u32 hash;
  158. __u32 minor_hash = 0;
  159. const char *p;
  160. int i;
  161. __u32 in[8], buf[4];
  162. /* Initialize the default seed for the hash checksum functions */
  163. buf[0] = 0x67452301;
  164. buf[1] = 0xefcdab89;
  165. buf[2] = 0x98badcfe;
  166. buf[3] = 0x10325476;
  167. /* Check to see if the seed is all zero's */
  168. if (seed) {
  169. for (i=0; i < 4; i++) {
  170. if (seed[i])
  171. break;
  172. }
  173. if (i < 4)
  174. memcpy(buf, seed, sizeof(buf));
  175. }
  176. switch (version) {
  177. case EXT2_HASH_LEGACY:
  178. hash = dx_hack_hash(name, len);
  179. break;
  180. case EXT2_HASH_HALF_MD4:
  181. p = name;
  182. while (len > 0) {
  183. str2hashbuf(p, len, in, 8);
  184. halfMD4Transform(buf, in);
  185. len -= 32;
  186. p += 32;
  187. }
  188. minor_hash = buf[2];
  189. hash = buf[1];
  190. break;
  191. case EXT2_HASH_TEA:
  192. p = name;
  193. while (len > 0) {
  194. str2hashbuf(p, len, in, 4);
  195. TEA_transform(buf, in);
  196. len -= 16;
  197. p += 16;
  198. }
  199. hash = buf[0];
  200. minor_hash = buf[1];
  201. break;
  202. default:
  203. *ret_hash = 0;
  204. return EXT2_ET_DIRHASH_UNSUPP;
  205. }
  206. *ret_hash = hash & ~1;
  207. if (ret_minor_hash)
  208. *ret_minor_hash = minor_hash;
  209. return 0;
  210. }