hash.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * fs/f2fs/hash.c
  4. *
  5. * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  6. * http://www.samsung.com/
  7. *
  8. * Portions of this code from linux/fs/ext3/hash.c
  9. *
  10. * Copyright (C) 2002 by Theodore Ts'o
  11. */
  12. #include <linux/types.h>
  13. #include <linux/fs.h>
  14. #include <linux/f2fs_fs.h>
  15. #include <linux/cryptohash.h>
  16. #include <linux/pagemap.h>
  17. #include "f2fs.h"
  18. /*
  19. * Hashing code copied from ext3
  20. */
  21. #define DELTA 0x9E3779B9
  22. static void TEA_transform(unsigned int buf[4], unsigned int const in[])
  23. {
  24. __u32 sum = 0;
  25. __u32 b0 = buf[0], b1 = buf[1];
  26. __u32 a = in[0], b = in[1], c = in[2], d = in[3];
  27. int n = 16;
  28. do {
  29. sum += DELTA;
  30. b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
  31. b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
  32. } while (--n);
  33. buf[0] += b0;
  34. buf[1] += b1;
  35. }
  36. static void str2hashbuf(const unsigned char *msg, size_t len,
  37. unsigned int *buf, int num)
  38. {
  39. unsigned pad, val;
  40. int i;
  41. pad = (__u32)len | ((__u32)len << 8);
  42. pad |= pad << 16;
  43. val = pad;
  44. if (len > num * 4)
  45. len = num * 4;
  46. for (i = 0; i < len; i++) {
  47. if ((i % 4) == 0)
  48. val = pad;
  49. val = msg[i] + (val << 8);
  50. if ((i % 4) == 3) {
  51. *buf++ = val;
  52. val = pad;
  53. num--;
  54. }
  55. }
  56. if (--num >= 0)
  57. *buf++ = val;
  58. while (--num >= 0)
  59. *buf++ = pad;
  60. }
  61. f2fs_hash_t f2fs_dentry_hash(const struct qstr *name_info,
  62. struct fscrypt_name *fname)
  63. {
  64. __u32 hash;
  65. f2fs_hash_t f2fs_hash;
  66. const unsigned char *p;
  67. __u32 in[8], buf[4];
  68. const unsigned char *name = name_info->name;
  69. size_t len = name_info->len;
  70. /* encrypted bigname case */
  71. if (fname && !fname->disk_name.name)
  72. return cpu_to_le32(fname->hash);
  73. if (is_dot_dotdot(name_info))
  74. return 0;
  75. /* Initialize the default seed for the hash checksum functions */
  76. buf[0] = 0x67452301;
  77. buf[1] = 0xefcdab89;
  78. buf[2] = 0x98badcfe;
  79. buf[3] = 0x10325476;
  80. p = name;
  81. while (1) {
  82. str2hashbuf(p, len, in, 4);
  83. TEA_transform(buf, in);
  84. p += 16;
  85. if (len <= 16)
  86. break;
  87. len -= 16;
  88. }
  89. hash = buf[0];
  90. f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT);
  91. return f2fs_hash;
  92. }