hash.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * linux/fs/ext4/hash.c
  3. *
  4. * Copyright (C) 2002 by Theodore Ts'o
  5. *
  6. * This file is released under the GPL v2.
  7. *
  8. * This file may be redistributed under the terms of the GNU Public
  9. * License.
  10. */
  11. #include <linux/fs.h>
  12. #include <linux/cryptohash.h>
  13. #include "ext4.h"
  14. #define DELTA 0x9E3779B9
  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. do {
  22. sum += DELTA;
  23. b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
  24. b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
  25. } while (--n);
  26. buf[0] += b0;
  27. buf[1] += b1;
  28. }
  29. /* The old legacy hash */
  30. static __u32 dx_hack_hash_unsigned(const char *name, int len)
  31. {
  32. __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
  33. const unsigned char *ucp = (const unsigned char *) name;
  34. while (len--) {
  35. hash = hash1 + (hash0 ^ (((int) *ucp++) * 7152373));
  36. if (hash & 0x80000000)
  37. hash -= 0x7fffffff;
  38. hash1 = hash0;
  39. hash0 = hash;
  40. }
  41. return hash0 << 1;
  42. }
  43. static __u32 dx_hack_hash_signed(const char *name, int len)
  44. {
  45. __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
  46. const signed char *scp = (const signed char *) name;
  47. while (len--) {
  48. hash = hash1 + (hash0 ^ (((int) *scp++) * 7152373));
  49. if (hash & 0x80000000)
  50. hash -= 0x7fffffff;
  51. hash1 = hash0;
  52. hash0 = hash;
  53. }
  54. return hash0 << 1;
  55. }
  56. static void str2hashbuf_signed(const char *msg, int len, __u32 *buf, int num)
  57. {
  58. __u32 pad, val;
  59. int i;
  60. const signed char *scp = (const signed char *) msg;
  61. pad = (__u32)len | ((__u32)len << 8);
  62. pad |= pad << 16;
  63. val = pad;
  64. if (len > num*4)
  65. len = num * 4;
  66. for (i = 0; i < len; i++) {
  67. if ((i % 4) == 0)
  68. val = pad;
  69. val = ((int) scp[i]) + (val << 8);
  70. if ((i % 4) == 3) {
  71. *buf++ = val;
  72. val = pad;
  73. num--;
  74. }
  75. }
  76. if (--num >= 0)
  77. *buf++ = val;
  78. while (--num >= 0)
  79. *buf++ = pad;
  80. }
  81. static void str2hashbuf_unsigned(const char *msg, int len, __u32 *buf, int num)
  82. {
  83. __u32 pad, val;
  84. int i;
  85. const unsigned char *ucp = (const unsigned char *) msg;
  86. pad = (__u32)len | ((__u32)len << 8);
  87. pad |= pad << 16;
  88. val = pad;
  89. if (len > num*4)
  90. len = num * 4;
  91. for (i = 0; i < len; i++) {
  92. if ((i % 4) == 0)
  93. val = pad;
  94. val = ((int) ucp[i]) + (val << 8);
  95. if ((i % 4) == 3) {
  96. *buf++ = val;
  97. val = pad;
  98. num--;
  99. }
  100. }
  101. if (--num >= 0)
  102. *buf++ = val;
  103. while (--num >= 0)
  104. *buf++ = pad;
  105. }
  106. /*
  107. * Returns the hash of a filename. If len is 0 and name is NULL, then
  108. * this function can be used to test whether or not a hash version is
  109. * supported.
  110. *
  111. * The seed is an 4 longword (32 bits) "secret" which can be used to
  112. * uniquify a hash. If the seed is all zero's, then some default seed
  113. * may be used.
  114. *
  115. * A particular hash version specifies whether or not the seed is
  116. * represented, and whether or not the returned hash is 32 bits or 64
  117. * bits. 32 bit hashes will return 0 for the minor hash.
  118. */
  119. int ext4fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
  120. {
  121. __u32 hash;
  122. __u32 minor_hash = 0;
  123. const char *p;
  124. int i;
  125. __u32 in[8], buf[4];
  126. void (*str2hashbuf)(const char *, int, __u32 *, int) =
  127. str2hashbuf_signed;
  128. /* Initialize the default seed for the hash checksum functions */
  129. buf[0] = 0x67452301;
  130. buf[1] = 0xefcdab89;
  131. buf[2] = 0x98badcfe;
  132. buf[3] = 0x10325476;
  133. /* Check to see if the seed is all zero's */
  134. if (hinfo->seed) {
  135. for (i = 0; i < 4; i++) {
  136. if (hinfo->seed[i]) {
  137. memcpy(buf, hinfo->seed, sizeof(buf));
  138. break;
  139. }
  140. }
  141. }
  142. switch (hinfo->hash_version) {
  143. case DX_HASH_LEGACY_UNSIGNED:
  144. hash = dx_hack_hash_unsigned(name, len);
  145. break;
  146. case DX_HASH_LEGACY:
  147. hash = dx_hack_hash_signed(name, len);
  148. break;
  149. case DX_HASH_HALF_MD4_UNSIGNED:
  150. str2hashbuf = str2hashbuf_unsigned;
  151. case DX_HASH_HALF_MD4:
  152. p = name;
  153. while (len > 0) {
  154. (*str2hashbuf)(p, len, in, 8);
  155. half_md4_transform(buf, in);
  156. len -= 32;
  157. p += 32;
  158. }
  159. minor_hash = buf[2];
  160. hash = buf[1];
  161. break;
  162. case DX_HASH_TEA_UNSIGNED:
  163. str2hashbuf = str2hashbuf_unsigned;
  164. case DX_HASH_TEA:
  165. p = name;
  166. while (len > 0) {
  167. (*str2hashbuf)(p, len, in, 4);
  168. TEA_transform(buf, in);
  169. len -= 16;
  170. p += 16;
  171. }
  172. hash = buf[0];
  173. minor_hash = buf[1];
  174. break;
  175. default:
  176. hinfo->hash = 0;
  177. return -1;
  178. }
  179. hash = hash & ~1;
  180. if (hash == (EXT4_HTREE_EOF_32BIT << 1))
  181. hash = (EXT4_HTREE_EOF_32BIT - 1) << 1;
  182. hinfo->hash = hash;
  183. hinfo->minor_hash = minor_hash;
  184. return 0;
  185. }