1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
6 * http://www.samsung.com/
8 * Portions of this code from linux/fs/ext3/hash.c
10 * Copyright (C) 2002 by Theodore Ts'o
12 #include <linux/types.h>
14 #include <linux/f2fs_fs.h>
15 #include <linux/pagemap.h>
16 #include <linux/unicode.h>
21 * Hashing code copied from ext3
23 #define DELTA 0x9E3779B9
25 static void TEA_transform(unsigned int buf
[4], unsigned int const in
[])
28 __u32 b0
= buf
[0], b1
= buf
[1];
29 __u32 a
= in
[0], b
= in
[1], c
= in
[2], d
= in
[3];
34 b0
+= ((b1
<< 4)+a
) ^ (b1
+sum
) ^ ((b1
>> 5)+b
);
35 b1
+= ((b0
<< 4)+c
) ^ (b0
+sum
) ^ ((b0
>> 5)+d
);
42 static void str2hashbuf(const unsigned char *msg
, size_t len
,
43 unsigned int *buf
, int num
)
48 pad
= (__u32
)len
| ((__u32
)len
<< 8);
54 for (i
= 0; i
< len
; i
++) {
57 val
= msg
[i
] + (val
<< 8);
70 static u32
TEA_hash_name(const u8
*p
, size_t len
)
74 /* Initialize the default seed for the hash checksum functions */
81 str2hashbuf(p
, len
, in
, 4);
82 TEA_transform(buf
, in
);
88 return buf
[0] & ~F2FS_HASH_COL_BIT
;
92 * Compute @fname->hash. For all directories, @fname->disk_name must be set.
93 * For casefolded directories, @fname->usr_fname must be set, and also
94 * @fname->cf_name if the filename is valid Unicode.
96 void f2fs_hash_filename(const struct inode
*dir
, struct f2fs_filename
*fname
)
98 const u8
*name
= fname
->disk_name
.name
;
99 size_t len
= fname
->disk_name
.len
;
103 if (is_dot_dotdot(name
, len
)) {
108 #ifdef CONFIG_UNICODE
109 if (IS_CASEFOLDED(dir
)) {
111 * If the casefolded name is provided, hash it instead of the
112 * on-disk name. If the casefolded name is *not* provided, that
113 * should only be because the name wasn't valid Unicode, so fall
114 * back to treating the name as an opaque byte sequence. Note
115 * that to handle encrypted directories, the fallback must use
116 * usr_fname (plaintext) rather than disk_name (ciphertext).
118 WARN_ON_ONCE(!fname
->usr_fname
->name
);
119 if (fname
->cf_name
.name
) {
120 name
= fname
->cf_name
.name
;
121 len
= fname
->cf_name
.len
;
123 name
= fname
->usr_fname
->name
;
124 len
= fname
->usr_fname
->len
;
126 if (IS_ENCRYPTED(dir
)) {
127 struct qstr tmp
= QSTR_INIT(name
, len
);
130 cpu_to_le32(fscrypt_fname_siphash(dir
, &tmp
));
135 fname
->hash
= cpu_to_le32(TEA_hash_name(name
, len
));