xref: /linux-6.15/include/linux/fscrypt.h (revision bb9cd910)
132190f0aSLinus Torvalds /* SPDX-License-Identifier: GPL-2.0 */
2734f0d24SDave Chinner /*
3734f0d24SDave Chinner  * fscrypt.h: declarations for per-file encryption
4734f0d24SDave Chinner  *
5643fa961SChandan Rajendra  * Filesystems that implement per-file encryption must include this header
6643fa961SChandan Rajendra  * file.
7734f0d24SDave Chinner  *
8734f0d24SDave Chinner  * Copyright (C) 2015, Google, Inc.
9734f0d24SDave Chinner  *
10734f0d24SDave Chinner  * Written by Michael Halcrow, 2015.
11734f0d24SDave Chinner  * Modified by Jaegeuk Kim, 2015.
12734f0d24SDave Chinner  */
13734f0d24SDave Chinner #ifndef _LINUX_FSCRYPT_H
14734f0d24SDave Chinner #define _LINUX_FSCRYPT_H
15734f0d24SDave Chinner 
16734f0d24SDave Chinner #include <linux/fs.h>
17643fa961SChandan Rajendra #include <linux/mm.h>
18643fa961SChandan Rajendra #include <linux/slab.h>
197af0ab0dSEric Biggers #include <uapi/linux/fscrypt.h>
20734f0d24SDave Chinner 
21734f0d24SDave Chinner #define FS_CRYPTO_BLOCK_SIZE		16
22734f0d24SDave Chinner 
23ac4acb1fSEric Biggers union fscrypt_policy;
24734f0d24SDave Chinner struct fscrypt_info;
25ed318a6cSEric Biggers struct seq_file;
26734f0d24SDave Chinner 
27734f0d24SDave Chinner struct fscrypt_str {
28734f0d24SDave Chinner 	unsigned char *name;
29734f0d24SDave Chinner 	u32 len;
30734f0d24SDave Chinner };
31734f0d24SDave Chinner 
32734f0d24SDave Chinner struct fscrypt_name {
33734f0d24SDave Chinner 	const struct qstr *usr_fname;
34734f0d24SDave Chinner 	struct fscrypt_str disk_name;
35734f0d24SDave Chinner 	u32 hash;
36734f0d24SDave Chinner 	u32 minor_hash;
37734f0d24SDave Chinner 	struct fscrypt_str crypto_buf;
3870fb2612SEric Biggers 	bool is_nokey_name;
39734f0d24SDave Chinner };
40734f0d24SDave Chinner 
41734f0d24SDave Chinner #define FSTR_INIT(n, l)		{ .name = n, .len = l }
42734f0d24SDave Chinner #define FSTR_TO_QSTR(f)		QSTR_INIT((f)->name, (f)->len)
43734f0d24SDave Chinner #define fname_name(p)		((p)->disk_name.name)
44734f0d24SDave Chinner #define fname_len(p)		((p)->disk_name.len)
45734f0d24SDave Chinner 
46734f0d24SDave Chinner /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
475dae460cSEric Biggers #define FSCRYPT_SET_CONTEXT_MAX_SIZE	40
48734f0d24SDave Chinner 
49643fa961SChandan Rajendra #ifdef CONFIG_FS_ENCRYPTION
50643fa961SChandan Rajendra /*
51643fa961SChandan Rajendra  * fscrypt superblock flags
52643fa961SChandan Rajendra  */
53643fa961SChandan Rajendra #define FS_CFLG_OWN_PAGES (1U << 1)
54643fa961SChandan Rajendra 
55643fa961SChandan Rajendra /*
56643fa961SChandan Rajendra  * crypto operations for filesystems
57643fa961SChandan Rajendra  */
58643fa961SChandan Rajendra struct fscrypt_operations {
59643fa961SChandan Rajendra 	unsigned int flags;
60643fa961SChandan Rajendra 	const char *key_prefix;
61fe015a78SEric Biggers 	int (*get_context)(struct inode *inode, void *ctx, size_t len);
62fe015a78SEric Biggers 	int (*set_context)(struct inode *inode, const void *ctx, size_t len,
63fe015a78SEric Biggers 			   void *fs_data);
64ac4acb1fSEric Biggers 	const union fscrypt_policy *(*get_dummy_policy)(struct super_block *sb);
65fe015a78SEric Biggers 	bool (*empty_dir)(struct inode *inode);
66643fa961SChandan Rajendra 	unsigned int max_namelen;
67b103fb76SEric Biggers 	bool (*has_stable_inodes)(struct super_block *sb);
68b103fb76SEric Biggers 	void (*get_ino_and_lblk_bits)(struct super_block *sb,
69b103fb76SEric Biggers 				      int *ino_bits_ret, int *lblk_bits_ret);
705fee3609SSatya Tangirala 	int (*get_num_devices)(struct super_block *sb);
715fee3609SSatya Tangirala 	void (*get_devices)(struct super_block *sb,
725fee3609SSatya Tangirala 			    struct request_queue **devs);
73643fa961SChandan Rajendra };
74643fa961SChandan Rajendra 
75ab673b98SEric Biggers static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode)
76643fa961SChandan Rajendra {
77ab673b98SEric Biggers 	/*
78ab673b98SEric Biggers 	 * Pairs with the cmpxchg_release() in fscrypt_get_encryption_info().
79ab673b98SEric Biggers 	 * I.e., another task may publish ->i_crypt_info concurrently, executing
80ab673b98SEric Biggers 	 * a RELEASE barrier.  We need to use smp_load_acquire() here to safely
81ab673b98SEric Biggers 	 * ACQUIRE the memory the other task published.
82ab673b98SEric Biggers 	 */
83ab673b98SEric Biggers 	return smp_load_acquire(&inode->i_crypt_info);
84643fa961SChandan Rajendra }
85643fa961SChandan Rajendra 
8656dce717SEric Biggers /**
8756dce717SEric Biggers  * fscrypt_needs_contents_encryption() - check whether an inode needs
8856dce717SEric Biggers  *					 contents encryption
89d2fe9754SEric Biggers  * @inode: the inode to check
9056dce717SEric Biggers  *
9156dce717SEric Biggers  * Return: %true iff the inode is an encrypted regular file and the kernel was
9256dce717SEric Biggers  * built with fscrypt support.
9356dce717SEric Biggers  *
9456dce717SEric Biggers  * If you need to know whether the encrypt bit is set even when the kernel was
9556dce717SEric Biggers  * built without fscrypt support, you must use IS_ENCRYPTED() directly instead.
9656dce717SEric Biggers  */
9756dce717SEric Biggers static inline bool fscrypt_needs_contents_encryption(const struct inode *inode)
9856dce717SEric Biggers {
9956dce717SEric Biggers 	return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
10056dce717SEric Biggers }
10156dce717SEric Biggers 
1020bf3d5c1SEric Biggers /*
103501e43fbSEric Biggers  * When d_splice_alias() moves a directory's no-key alias to its plaintext alias
104501e43fbSEric Biggers  * as a result of the encryption key being added, DCACHE_NOKEY_NAME must be
105501e43fbSEric Biggers  * cleared.  Note that we don't have to support arbitrary moves of this flag
106501e43fbSEric Biggers  * because fscrypt doesn't allow no-key names to be the source or target of a
107501e43fbSEric Biggers  * rename().
1080bf3d5c1SEric Biggers  */
1090bf3d5c1SEric Biggers static inline void fscrypt_handle_d_move(struct dentry *dentry)
1100bf3d5c1SEric Biggers {
111501e43fbSEric Biggers 	dentry->d_flags &= ~DCACHE_NOKEY_NAME;
1120bf3d5c1SEric Biggers }
1130bf3d5c1SEric Biggers 
114643fa961SChandan Rajendra /* crypto.c */
11560700902SEric Biggers void fscrypt_enqueue_decrypt_work(struct work_struct *);
11653bc1d85SEric Biggers 
11760700902SEric Biggers struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
11853bc1d85SEric Biggers 					      unsigned int len,
11953bc1d85SEric Biggers 					      unsigned int offs,
12053bc1d85SEric Biggers 					      gfp_t gfp_flags);
12160700902SEric Biggers int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
12260700902SEric Biggers 				  unsigned int len, unsigned int offs,
12360700902SEric Biggers 				  u64 lblk_num, gfp_t gfp_flags);
124aa8bc1acSEric Biggers 
12560700902SEric Biggers int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len,
126aa8bc1acSEric Biggers 				     unsigned int offs);
12760700902SEric Biggers int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
12860700902SEric Biggers 				  unsigned int len, unsigned int offs,
12960700902SEric Biggers 				  u64 lblk_num);
130643fa961SChandan Rajendra 
131d2d0727bSEric Biggers static inline bool fscrypt_is_bounce_page(struct page *page)
132643fa961SChandan Rajendra {
133d2d0727bSEric Biggers 	return page->mapping == NULL;
134643fa961SChandan Rajendra }
135643fa961SChandan Rajendra 
136d2d0727bSEric Biggers static inline struct page *fscrypt_pagecache_page(struct page *bounce_page)
137d2d0727bSEric Biggers {
138d2d0727bSEric Biggers 	return (struct page *)page_private(bounce_page);
139d2d0727bSEric Biggers }
140d2d0727bSEric Biggers 
14160700902SEric Biggers void fscrypt_free_bounce_page(struct page *bounce_page);
142643fa961SChandan Rajendra 
143643fa961SChandan Rajendra /* policy.c */
14460700902SEric Biggers int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg);
14560700902SEric Biggers int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg);
14660700902SEric Biggers int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg);
14760700902SEric Biggers int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg);
14860700902SEric Biggers int fscrypt_has_permitted_context(struct inode *parent, struct inode *child);
149a992b20cSEric Biggers int fscrypt_set_context(struct inode *inode, void *fs_data);
150fe015a78SEric Biggers 
151ac4acb1fSEric Biggers struct fscrypt_dummy_policy {
152ac4acb1fSEric Biggers 	const union fscrypt_policy *policy;
153ed318a6cSEric Biggers };
154ed318a6cSEric Biggers 
155c8c868abSEric Biggers int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg,
156ac4acb1fSEric Biggers 				struct fscrypt_dummy_policy *dummy_policy);
157ed318a6cSEric Biggers void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep,
158ed318a6cSEric Biggers 					struct super_block *sb);
159ed318a6cSEric Biggers static inline void
160ac4acb1fSEric Biggers fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
161ed318a6cSEric Biggers {
162ac4acb1fSEric Biggers 	kfree(dummy_policy->policy);
163ac4acb1fSEric Biggers 	dummy_policy->policy = NULL;
164ed318a6cSEric Biggers }
165ed318a6cSEric Biggers 
16622d94f49SEric Biggers /* keyring.c */
16760700902SEric Biggers void fscrypt_sb_free(struct super_block *sb);
16860700902SEric Biggers int fscrypt_ioctl_add_key(struct file *filp, void __user *arg);
16960700902SEric Biggers int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg);
17060700902SEric Biggers int fscrypt_ioctl_remove_key_all_users(struct file *filp, void __user *arg);
17160700902SEric Biggers int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg);
17222d94f49SEric Biggers 
173feed8258SEric Biggers /* keysetup.c */
17460700902SEric Biggers int fscrypt_get_encryption_info(struct inode *inode);
175a992b20cSEric Biggers int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
176a992b20cSEric Biggers 			      bool *encrypt_ret);
17760700902SEric Biggers void fscrypt_put_encryption_info(struct inode *inode);
17860700902SEric Biggers void fscrypt_free_inode(struct inode *inode);
17960700902SEric Biggers int fscrypt_drop_inode(struct inode *inode);
180643fa961SChandan Rajendra 
181643fa961SChandan Rajendra /* fname.c */
18260700902SEric Biggers int fscrypt_setup_filename(struct inode *inode, const struct qstr *iname,
183fe015a78SEric Biggers 			   int lookup, struct fscrypt_name *fname);
184643fa961SChandan Rajendra 
185643fa961SChandan Rajendra static inline void fscrypt_free_filename(struct fscrypt_name *fname)
186643fa961SChandan Rajendra {
187643fa961SChandan Rajendra 	kfree(fname->crypto_buf.name);
188643fa961SChandan Rajendra }
189643fa961SChandan Rajendra 
1908b10fe68SJeff Layton int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
191fe015a78SEric Biggers 			       struct fscrypt_str *crypto_str);
19260700902SEric Biggers void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str);
19360700902SEric Biggers int fscrypt_fname_disk_to_usr(const struct inode *inode,
1948a4ab0b8SEric Biggers 			      u32 hash, u32 minor_hash,
1958a4ab0b8SEric Biggers 			      const struct fscrypt_str *iname,
1968a4ab0b8SEric Biggers 			      struct fscrypt_str *oname);
19760700902SEric Biggers bool fscrypt_match_name(const struct fscrypt_name *fname,
198edc440e3SDaniel Rosenberg 			const u8 *de_name, u32 de_name_len);
19960700902SEric Biggers u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name);
2005b2a828bSEric Biggers int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags);
201aa408f83SDaniel Rosenberg 
202643fa961SChandan Rajendra /* bio.c */
20360700902SEric Biggers void fscrypt_decrypt_bio(struct bio *bio);
20460700902SEric Biggers int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
205fe015a78SEric Biggers 			  sector_t pblk, unsigned int len);
206643fa961SChandan Rajendra 
207643fa961SChandan Rajendra /* hooks.c */
20860700902SEric Biggers int fscrypt_file_open(struct inode *inode, struct file *filp);
20960700902SEric Biggers int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
210968dd6d0SEric Biggers 			   struct dentry *dentry);
21160700902SEric Biggers int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
21260700902SEric Biggers 			     struct inode *new_dir, struct dentry *new_dentry,
213643fa961SChandan Rajendra 			     unsigned int flags);
21460700902SEric Biggers int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
215b01531dbSEric Biggers 			     struct fscrypt_name *fname);
21660700902SEric Biggers int fscrypt_prepare_setflags(struct inode *inode,
2176e1918cfSDaniel Rosenberg 			     unsigned int oldflags, unsigned int flags);
21831114726SEric Biggers int fscrypt_prepare_symlink(struct inode *dir, const char *target,
21931114726SEric Biggers 			    unsigned int len, unsigned int max_len,
220643fa961SChandan Rajendra 			    struct fscrypt_str *disk_link);
22160700902SEric Biggers int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
22260700902SEric Biggers 			      unsigned int len, struct fscrypt_str *disk_link);
22360700902SEric Biggers const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
224643fa961SChandan Rajendra 				unsigned int max_size,
225643fa961SChandan Rajendra 				struct delayed_call *done);
226eea2c05dSSascha Hauer static inline void fscrypt_set_ops(struct super_block *sb,
227eea2c05dSSascha Hauer 				   const struct fscrypt_operations *s_cop)
228eea2c05dSSascha Hauer {
229eea2c05dSSascha Hauer 	sb->s_cop = s_cop;
230eea2c05dSSascha Hauer }
231643fa961SChandan Rajendra #else  /* !CONFIG_FS_ENCRYPTION */
232643fa961SChandan Rajendra 
233ab673b98SEric Biggers static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode)
234643fa961SChandan Rajendra {
235ab673b98SEric Biggers 	return NULL;
236643fa961SChandan Rajendra }
237643fa961SChandan Rajendra 
23856dce717SEric Biggers static inline bool fscrypt_needs_contents_encryption(const struct inode *inode)
23956dce717SEric Biggers {
24056dce717SEric Biggers 	return false;
24156dce717SEric Biggers }
24256dce717SEric Biggers 
2430bf3d5c1SEric Biggers static inline void fscrypt_handle_d_move(struct dentry *dentry)
2440bf3d5c1SEric Biggers {
2450bf3d5c1SEric Biggers }
2460bf3d5c1SEric Biggers 
247643fa961SChandan Rajendra /* crypto.c */
248643fa961SChandan Rajendra static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
249643fa961SChandan Rajendra {
250643fa961SChandan Rajendra }
251643fa961SChandan Rajendra 
25253bc1d85SEric Biggers static inline struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
253643fa961SChandan Rajendra 							    unsigned int len,
254643fa961SChandan Rajendra 							    unsigned int offs,
25553bc1d85SEric Biggers 							    gfp_t gfp_flags)
256643fa961SChandan Rajendra {
257643fa961SChandan Rajendra 	return ERR_PTR(-EOPNOTSUPP);
258643fa961SChandan Rajendra }
259643fa961SChandan Rajendra 
26003569f2fSEric Biggers static inline int fscrypt_encrypt_block_inplace(const struct inode *inode,
26103569f2fSEric Biggers 						struct page *page,
26203569f2fSEric Biggers 						unsigned int len,
26303569f2fSEric Biggers 						unsigned int offs, u64 lblk_num,
26403569f2fSEric Biggers 						gfp_t gfp_flags)
26503569f2fSEric Biggers {
26603569f2fSEric Biggers 	return -EOPNOTSUPP;
26703569f2fSEric Biggers }
26803569f2fSEric Biggers 
269aa8bc1acSEric Biggers static inline int fscrypt_decrypt_pagecache_blocks(struct page *page,
270aa8bc1acSEric Biggers 						   unsigned int len,
271aa8bc1acSEric Biggers 						   unsigned int offs)
272643fa961SChandan Rajendra {
273643fa961SChandan Rajendra 	return -EOPNOTSUPP;
274643fa961SChandan Rajendra }
275643fa961SChandan Rajendra 
27641adbcb7SEric Biggers static inline int fscrypt_decrypt_block_inplace(const struct inode *inode,
27741adbcb7SEric Biggers 						struct page *page,
27841adbcb7SEric Biggers 						unsigned int len,
27941adbcb7SEric Biggers 						unsigned int offs, u64 lblk_num)
28041adbcb7SEric Biggers {
28141adbcb7SEric Biggers 	return -EOPNOTSUPP;
28241adbcb7SEric Biggers }
28341adbcb7SEric Biggers 
284d2d0727bSEric Biggers static inline bool fscrypt_is_bounce_page(struct page *page)
285d2d0727bSEric Biggers {
286d2d0727bSEric Biggers 	return false;
287d2d0727bSEric Biggers }
288d2d0727bSEric Biggers 
289d2d0727bSEric Biggers static inline struct page *fscrypt_pagecache_page(struct page *bounce_page)
290643fa961SChandan Rajendra {
291643fa961SChandan Rajendra 	WARN_ON_ONCE(1);
292643fa961SChandan Rajendra 	return ERR_PTR(-EINVAL);
293643fa961SChandan Rajendra }
294643fa961SChandan Rajendra 
295d2d0727bSEric Biggers static inline void fscrypt_free_bounce_page(struct page *bounce_page)
296643fa961SChandan Rajendra {
297643fa961SChandan Rajendra }
298643fa961SChandan Rajendra 
299643fa961SChandan Rajendra /* policy.c */
300643fa961SChandan Rajendra static inline int fscrypt_ioctl_set_policy(struct file *filp,
301643fa961SChandan Rajendra 					   const void __user *arg)
302643fa961SChandan Rajendra {
303643fa961SChandan Rajendra 	return -EOPNOTSUPP;
304643fa961SChandan Rajendra }
305643fa961SChandan Rajendra 
306643fa961SChandan Rajendra static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
307643fa961SChandan Rajendra {
308643fa961SChandan Rajendra 	return -EOPNOTSUPP;
309643fa961SChandan Rajendra }
310643fa961SChandan Rajendra 
3115dae460cSEric Biggers static inline int fscrypt_ioctl_get_policy_ex(struct file *filp,
3125dae460cSEric Biggers 					      void __user *arg)
3135dae460cSEric Biggers {
3145dae460cSEric Biggers 	return -EOPNOTSUPP;
3155dae460cSEric Biggers }
3165dae460cSEric Biggers 
317e98ad464SEric Biggers static inline int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg)
318e98ad464SEric Biggers {
319e98ad464SEric Biggers 	return -EOPNOTSUPP;
320e98ad464SEric Biggers }
321e98ad464SEric Biggers 
322643fa961SChandan Rajendra static inline int fscrypt_has_permitted_context(struct inode *parent,
323643fa961SChandan Rajendra 						struct inode *child)
324643fa961SChandan Rajendra {
325643fa961SChandan Rajendra 	return 0;
326643fa961SChandan Rajendra }
327643fa961SChandan Rajendra 
328a992b20cSEric Biggers static inline int fscrypt_set_context(struct inode *inode, void *fs_data)
329a992b20cSEric Biggers {
330a992b20cSEric Biggers 	return -EOPNOTSUPP;
331a992b20cSEric Biggers }
332a992b20cSEric Biggers 
333ac4acb1fSEric Biggers struct fscrypt_dummy_policy {
334ed318a6cSEric Biggers };
335ed318a6cSEric Biggers 
336ed318a6cSEric Biggers static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq,
337ed318a6cSEric Biggers 						      char sep,
338ed318a6cSEric Biggers 						      struct super_block *sb)
339ed318a6cSEric Biggers {
340ed318a6cSEric Biggers }
341ed318a6cSEric Biggers 
342ed318a6cSEric Biggers static inline void
343ac4acb1fSEric Biggers fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
344ed318a6cSEric Biggers {
345ed318a6cSEric Biggers }
346ed318a6cSEric Biggers 
34722d94f49SEric Biggers /* keyring.c */
34822d94f49SEric Biggers static inline void fscrypt_sb_free(struct super_block *sb)
34922d94f49SEric Biggers {
35022d94f49SEric Biggers }
35122d94f49SEric Biggers 
35222d94f49SEric Biggers static inline int fscrypt_ioctl_add_key(struct file *filp, void __user *arg)
35322d94f49SEric Biggers {
35422d94f49SEric Biggers 	return -EOPNOTSUPP;
35522d94f49SEric Biggers }
35622d94f49SEric Biggers 
357b1c0ec35SEric Biggers static inline int fscrypt_ioctl_remove_key(struct file *filp, void __user *arg)
358b1c0ec35SEric Biggers {
359b1c0ec35SEric Biggers 	return -EOPNOTSUPP;
360b1c0ec35SEric Biggers }
361b1c0ec35SEric Biggers 
36278a1b96bSEric Biggers static inline int fscrypt_ioctl_remove_key_all_users(struct file *filp,
36378a1b96bSEric Biggers 						     void __user *arg)
36478a1b96bSEric Biggers {
36578a1b96bSEric Biggers 	return -EOPNOTSUPP;
36678a1b96bSEric Biggers }
36778a1b96bSEric Biggers 
3685a7e2992SEric Biggers static inline int fscrypt_ioctl_get_key_status(struct file *filp,
3695a7e2992SEric Biggers 					       void __user *arg)
3705a7e2992SEric Biggers {
3715a7e2992SEric Biggers 	return -EOPNOTSUPP;
3725a7e2992SEric Biggers }
3735a7e2992SEric Biggers 
374feed8258SEric Biggers /* keysetup.c */
375643fa961SChandan Rajendra static inline int fscrypt_get_encryption_info(struct inode *inode)
376643fa961SChandan Rajendra {
377643fa961SChandan Rajendra 	return -EOPNOTSUPP;
378643fa961SChandan Rajendra }
379643fa961SChandan Rajendra 
380a992b20cSEric Biggers static inline int fscrypt_prepare_new_inode(struct inode *dir,
381a992b20cSEric Biggers 					    struct inode *inode,
382a992b20cSEric Biggers 					    bool *encrypt_ret)
383a992b20cSEric Biggers {
384a992b20cSEric Biggers 	if (IS_ENCRYPTED(dir))
385a992b20cSEric Biggers 		return -EOPNOTSUPP;
386a992b20cSEric Biggers 	return 0;
387a992b20cSEric Biggers }
388a992b20cSEric Biggers 
389643fa961SChandan Rajendra static inline void fscrypt_put_encryption_info(struct inode *inode)
390643fa961SChandan Rajendra {
391643fa961SChandan Rajendra 	return;
392643fa961SChandan Rajendra }
393643fa961SChandan Rajendra 
3942c58d548SEric Biggers static inline void fscrypt_free_inode(struct inode *inode)
3952c58d548SEric Biggers {
3962c58d548SEric Biggers }
3972c58d548SEric Biggers 
398b1c0ec35SEric Biggers static inline int fscrypt_drop_inode(struct inode *inode)
399b1c0ec35SEric Biggers {
400b1c0ec35SEric Biggers 	return 0;
401b1c0ec35SEric Biggers }
402b1c0ec35SEric Biggers 
403643fa961SChandan Rajendra  /* fname.c */
404643fa961SChandan Rajendra static inline int fscrypt_setup_filename(struct inode *dir,
405643fa961SChandan Rajendra 					 const struct qstr *iname,
406643fa961SChandan Rajendra 					 int lookup, struct fscrypt_name *fname)
407643fa961SChandan Rajendra {
408643fa961SChandan Rajendra 	if (IS_ENCRYPTED(dir))
409643fa961SChandan Rajendra 		return -EOPNOTSUPP;
410643fa961SChandan Rajendra 
411b01531dbSEric Biggers 	memset(fname, 0, sizeof(*fname));
412643fa961SChandan Rajendra 	fname->usr_fname = iname;
413643fa961SChandan Rajendra 	fname->disk_name.name = (unsigned char *)iname->name;
414643fa961SChandan Rajendra 	fname->disk_name.len = iname->len;
415643fa961SChandan Rajendra 	return 0;
416643fa961SChandan Rajendra }
417643fa961SChandan Rajendra 
418643fa961SChandan Rajendra static inline void fscrypt_free_filename(struct fscrypt_name *fname)
419643fa961SChandan Rajendra {
420643fa961SChandan Rajendra 	return;
421643fa961SChandan Rajendra }
422643fa961SChandan Rajendra 
4238b10fe68SJeff Layton static inline int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
424643fa961SChandan Rajendra 					     struct fscrypt_str *crypto_str)
425643fa961SChandan Rajendra {
426643fa961SChandan Rajendra 	return -EOPNOTSUPP;
427643fa961SChandan Rajendra }
428643fa961SChandan Rajendra 
429643fa961SChandan Rajendra static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
430643fa961SChandan Rajendra {
431643fa961SChandan Rajendra 	return;
432643fa961SChandan Rajendra }
433643fa961SChandan Rajendra 
4348a4ab0b8SEric Biggers static inline int fscrypt_fname_disk_to_usr(const struct inode *inode,
435643fa961SChandan Rajendra 					    u32 hash, u32 minor_hash,
436643fa961SChandan Rajendra 					    const struct fscrypt_str *iname,
437643fa961SChandan Rajendra 					    struct fscrypt_str *oname)
438643fa961SChandan Rajendra {
439643fa961SChandan Rajendra 	return -EOPNOTSUPP;
440643fa961SChandan Rajendra }
441643fa961SChandan Rajendra 
442643fa961SChandan Rajendra static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
443643fa961SChandan Rajendra 				      const u8 *de_name, u32 de_name_len)
444643fa961SChandan Rajendra {
445643fa961SChandan Rajendra 	/* Encryption support disabled; use standard comparison */
446643fa961SChandan Rajendra 	if (de_name_len != fname->disk_name.len)
447643fa961SChandan Rajendra 		return false;
448643fa961SChandan Rajendra 	return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
449643fa961SChandan Rajendra }
450643fa961SChandan Rajendra 
451aa408f83SDaniel Rosenberg static inline u64 fscrypt_fname_siphash(const struct inode *dir,
452aa408f83SDaniel Rosenberg 					const struct qstr *name)
453aa408f83SDaniel Rosenberg {
454aa408f83SDaniel Rosenberg 	WARN_ON_ONCE(1);
455aa408f83SDaniel Rosenberg 	return 0;
456aa408f83SDaniel Rosenberg }
457aa408f83SDaniel Rosenberg 
4585b2a828bSEric Biggers static inline int fscrypt_d_revalidate(struct dentry *dentry,
4595b2a828bSEric Biggers 				       unsigned int flags)
4605b2a828bSEric Biggers {
4615b2a828bSEric Biggers 	return 1;
4625b2a828bSEric Biggers }
4635b2a828bSEric Biggers 
464643fa961SChandan Rajendra /* bio.c */
465643fa961SChandan Rajendra static inline void fscrypt_decrypt_bio(struct bio *bio)
466643fa961SChandan Rajendra {
467643fa961SChandan Rajendra }
468643fa961SChandan Rajendra 
469643fa961SChandan Rajendra static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
470643fa961SChandan Rajendra 					sector_t pblk, unsigned int len)
471643fa961SChandan Rajendra {
472643fa961SChandan Rajendra 	return -EOPNOTSUPP;
473643fa961SChandan Rajendra }
474643fa961SChandan Rajendra 
475643fa961SChandan Rajendra /* hooks.c */
476643fa961SChandan Rajendra 
477643fa961SChandan Rajendra static inline int fscrypt_file_open(struct inode *inode, struct file *filp)
478643fa961SChandan Rajendra {
479643fa961SChandan Rajendra 	if (IS_ENCRYPTED(inode))
480643fa961SChandan Rajendra 		return -EOPNOTSUPP;
481643fa961SChandan Rajendra 	return 0;
482643fa961SChandan Rajendra }
483643fa961SChandan Rajendra 
484968dd6d0SEric Biggers static inline int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
485968dd6d0SEric Biggers 					 struct dentry *dentry)
486643fa961SChandan Rajendra {
487643fa961SChandan Rajendra 	return -EOPNOTSUPP;
488643fa961SChandan Rajendra }
489643fa961SChandan Rajendra 
490643fa961SChandan Rajendra static inline int __fscrypt_prepare_rename(struct inode *old_dir,
491643fa961SChandan Rajendra 					   struct dentry *old_dentry,
492643fa961SChandan Rajendra 					   struct inode *new_dir,
493643fa961SChandan Rajendra 					   struct dentry *new_dentry,
494643fa961SChandan Rajendra 					   unsigned int flags)
495643fa961SChandan Rajendra {
496643fa961SChandan Rajendra 	return -EOPNOTSUPP;
497643fa961SChandan Rajendra }
498643fa961SChandan Rajendra 
499643fa961SChandan Rajendra static inline int __fscrypt_prepare_lookup(struct inode *dir,
500b01531dbSEric Biggers 					   struct dentry *dentry,
501b01531dbSEric Biggers 					   struct fscrypt_name *fname)
502643fa961SChandan Rajendra {
503643fa961SChandan Rajendra 	return -EOPNOTSUPP;
504643fa961SChandan Rajendra }
505643fa961SChandan Rajendra 
5066e1918cfSDaniel Rosenberg static inline int fscrypt_prepare_setflags(struct inode *inode,
5076e1918cfSDaniel Rosenberg 					   unsigned int oldflags,
5086e1918cfSDaniel Rosenberg 					   unsigned int flags)
5096e1918cfSDaniel Rosenberg {
5106e1918cfSDaniel Rosenberg 	return 0;
5116e1918cfSDaniel Rosenberg }
5126e1918cfSDaniel Rosenberg 
51331114726SEric Biggers static inline int fscrypt_prepare_symlink(struct inode *dir,
51431114726SEric Biggers 					  const char *target,
515643fa961SChandan Rajendra 					  unsigned int len,
516643fa961SChandan Rajendra 					  unsigned int max_len,
517643fa961SChandan Rajendra 					  struct fscrypt_str *disk_link)
518643fa961SChandan Rajendra {
51931114726SEric Biggers 	if (IS_ENCRYPTED(dir))
520643fa961SChandan Rajendra 		return -EOPNOTSUPP;
52131114726SEric Biggers 	disk_link->name = (unsigned char *)target;
52231114726SEric Biggers 	disk_link->len = len + 1;
52331114726SEric Biggers 	if (disk_link->len > max_len)
52431114726SEric Biggers 		return -ENAMETOOLONG;
52531114726SEric Biggers 	return 0;
526643fa961SChandan Rajendra }
527643fa961SChandan Rajendra 
528643fa961SChandan Rajendra static inline int __fscrypt_encrypt_symlink(struct inode *inode,
529643fa961SChandan Rajendra 					    const char *target,
530643fa961SChandan Rajendra 					    unsigned int len,
531643fa961SChandan Rajendra 					    struct fscrypt_str *disk_link)
532643fa961SChandan Rajendra {
533643fa961SChandan Rajendra 	return -EOPNOTSUPP;
534643fa961SChandan Rajendra }
535643fa961SChandan Rajendra 
536643fa961SChandan Rajendra static inline const char *fscrypt_get_symlink(struct inode *inode,
537643fa961SChandan Rajendra 					      const void *caddr,
538643fa961SChandan Rajendra 					      unsigned int max_size,
539643fa961SChandan Rajendra 					      struct delayed_call *done)
540643fa961SChandan Rajendra {
541643fa961SChandan Rajendra 	return ERR_PTR(-EOPNOTSUPP);
542643fa961SChandan Rajendra }
543eea2c05dSSascha Hauer 
544eea2c05dSSascha Hauer static inline void fscrypt_set_ops(struct super_block *sb,
545eea2c05dSSascha Hauer 				   const struct fscrypt_operations *s_cop)
546eea2c05dSSascha Hauer {
547eea2c05dSSascha Hauer }
548eea2c05dSSascha Hauer 
549643fa961SChandan Rajendra #endif	/* !CONFIG_FS_ENCRYPTION */
550734f0d24SDave Chinner 
5515fee3609SSatya Tangirala /* inline_crypt.c */
5525fee3609SSatya Tangirala #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
5535fee3609SSatya Tangirala 
5545fee3609SSatya Tangirala bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode);
5555fee3609SSatya Tangirala 
5565fee3609SSatya Tangirala void fscrypt_set_bio_crypt_ctx(struct bio *bio,
5575fee3609SSatya Tangirala 			       const struct inode *inode, u64 first_lblk,
5585fee3609SSatya Tangirala 			       gfp_t gfp_mask);
5595fee3609SSatya Tangirala 
5605fee3609SSatya Tangirala void fscrypt_set_bio_crypt_ctx_bh(struct bio *bio,
5615fee3609SSatya Tangirala 				  const struct buffer_head *first_bh,
5625fee3609SSatya Tangirala 				  gfp_t gfp_mask);
5635fee3609SSatya Tangirala 
5645fee3609SSatya Tangirala bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
5655fee3609SSatya Tangirala 			   u64 next_lblk);
5665fee3609SSatya Tangirala 
5675fee3609SSatya Tangirala bool fscrypt_mergeable_bio_bh(struct bio *bio,
5685fee3609SSatya Tangirala 			      const struct buffer_head *next_bh);
5695fee3609SSatya Tangirala 
5705fee3609SSatya Tangirala #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
5715fee3609SSatya Tangirala 
5725fee3609SSatya Tangirala static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
5735fee3609SSatya Tangirala {
5745fee3609SSatya Tangirala 	return false;
5755fee3609SSatya Tangirala }
5765fee3609SSatya Tangirala 
5775fee3609SSatya Tangirala static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio,
5785fee3609SSatya Tangirala 					     const struct inode *inode,
5795fee3609SSatya Tangirala 					     u64 first_lblk, gfp_t gfp_mask) { }
5805fee3609SSatya Tangirala 
5815fee3609SSatya Tangirala static inline void fscrypt_set_bio_crypt_ctx_bh(
5825fee3609SSatya Tangirala 					 struct bio *bio,
5835fee3609SSatya Tangirala 					 const struct buffer_head *first_bh,
5845fee3609SSatya Tangirala 					 gfp_t gfp_mask) { }
5855fee3609SSatya Tangirala 
5865fee3609SSatya Tangirala static inline bool fscrypt_mergeable_bio(struct bio *bio,
5875fee3609SSatya Tangirala 					 const struct inode *inode,
5885fee3609SSatya Tangirala 					 u64 next_lblk)
5895fee3609SSatya Tangirala {
5905fee3609SSatya Tangirala 	return true;
5915fee3609SSatya Tangirala }
5925fee3609SSatya Tangirala 
5935fee3609SSatya Tangirala static inline bool fscrypt_mergeable_bio_bh(struct bio *bio,
5945fee3609SSatya Tangirala 					    const struct buffer_head *next_bh)
5955fee3609SSatya Tangirala {
5965fee3609SSatya Tangirala 	return true;
5975fee3609SSatya Tangirala }
5985fee3609SSatya Tangirala #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
5995fee3609SSatya Tangirala 
6005fee3609SSatya Tangirala /**
6015fee3609SSatya Tangirala  * fscrypt_inode_uses_inline_crypto() - test whether an inode uses inline
6025fee3609SSatya Tangirala  *					encryption
6035fee3609SSatya Tangirala  * @inode: an inode. If encrypted, its key must be set up.
6045fee3609SSatya Tangirala  *
6055fee3609SSatya Tangirala  * Return: true if the inode requires file contents encryption and if the
6065fee3609SSatya Tangirala  *	   encryption should be done in the block layer via blk-crypto rather
6075fee3609SSatya Tangirala  *	   than in the filesystem layer.
6085fee3609SSatya Tangirala  */
6095fee3609SSatya Tangirala static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode)
6105fee3609SSatya Tangirala {
6115fee3609SSatya Tangirala 	return fscrypt_needs_contents_encryption(inode) &&
6125fee3609SSatya Tangirala 	       __fscrypt_inode_uses_inline_crypto(inode);
6135fee3609SSatya Tangirala }
6145fee3609SSatya Tangirala 
6155fee3609SSatya Tangirala /**
6165fee3609SSatya Tangirala  * fscrypt_inode_uses_fs_layer_crypto() - test whether an inode uses fs-layer
6175fee3609SSatya Tangirala  *					  encryption
6185fee3609SSatya Tangirala  * @inode: an inode. If encrypted, its key must be set up.
6195fee3609SSatya Tangirala  *
6205fee3609SSatya Tangirala  * Return: true if the inode requires file contents encryption and if the
6215fee3609SSatya Tangirala  *	   encryption should be done in the filesystem layer rather than in the
6225fee3609SSatya Tangirala  *	   block layer via blk-crypto.
6235fee3609SSatya Tangirala  */
6245fee3609SSatya Tangirala static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode)
6255fee3609SSatya Tangirala {
6265fee3609SSatya Tangirala 	return fscrypt_needs_contents_encryption(inode) &&
6275fee3609SSatya Tangirala 	       !__fscrypt_inode_uses_inline_crypto(inode);
6285fee3609SSatya Tangirala }
6295fee3609SSatya Tangirala 
630d293c3e4SEric Biggers /**
631ab673b98SEric Biggers  * fscrypt_has_encryption_key() - check whether an inode has had its key set up
632ab673b98SEric Biggers  * @inode: the inode to check
633ab673b98SEric Biggers  *
634ab673b98SEric Biggers  * Return: %true if the inode has had its encryption key set up, else %false.
635ab673b98SEric Biggers  *
636ab673b98SEric Biggers  * Usually this should be preceded by fscrypt_get_encryption_info() to try to
637ab673b98SEric Biggers  * set up the key first.
638ab673b98SEric Biggers  */
639ab673b98SEric Biggers static inline bool fscrypt_has_encryption_key(const struct inode *inode)
640ab673b98SEric Biggers {
641ab673b98SEric Biggers 	return fscrypt_get_info(inode) != NULL;
642ab673b98SEric Biggers }
643ab673b98SEric Biggers 
644ab673b98SEric Biggers /**
645d2fe9754SEric Biggers  * fscrypt_require_key() - require an inode's encryption key
646d293c3e4SEric Biggers  * @inode: the inode we need the key for
647d293c3e4SEric Biggers  *
648d293c3e4SEric Biggers  * If the inode is encrypted, set up its encryption key if not already done.
649d293c3e4SEric Biggers  * Then require that the key be present and return -ENOKEY otherwise.
650d293c3e4SEric Biggers  *
651d293c3e4SEric Biggers  * No locks are needed, and the key will live as long as the struct inode --- so
652d293c3e4SEric Biggers  * it won't go away from under you.
653d293c3e4SEric Biggers  *
654d293c3e4SEric Biggers  * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code
655d293c3e4SEric Biggers  * if a problem occurred while setting up the encryption key.
656d293c3e4SEric Biggers  */
657d293c3e4SEric Biggers static inline int fscrypt_require_key(struct inode *inode)
658d293c3e4SEric Biggers {
659d293c3e4SEric Biggers 	if (IS_ENCRYPTED(inode)) {
660d293c3e4SEric Biggers 		int err = fscrypt_get_encryption_info(inode);
661d293c3e4SEric Biggers 
662d293c3e4SEric Biggers 		if (err)
663d293c3e4SEric Biggers 			return err;
664d293c3e4SEric Biggers 		if (!fscrypt_has_encryption_key(inode))
665d293c3e4SEric Biggers 			return -ENOKEY;
666d293c3e4SEric Biggers 	}
667d293c3e4SEric Biggers 	return 0;
668d293c3e4SEric Biggers }
669734f0d24SDave Chinner 
6700ea87a96SEric Biggers /**
671d2fe9754SEric Biggers  * fscrypt_prepare_link() - prepare to link an inode into a possibly-encrypted
672d2fe9754SEric Biggers  *			    directory
6730ea87a96SEric Biggers  * @old_dentry: an existing dentry for the inode being linked
6740ea87a96SEric Biggers  * @dir: the target directory
6750ea87a96SEric Biggers  * @dentry: negative dentry for the target filename
6760ea87a96SEric Biggers  *
6770ea87a96SEric Biggers  * A new link can only be added to an encrypted directory if the directory's
6780ea87a96SEric Biggers  * encryption key is available --- since otherwise we'd have no way to encrypt
6790ea87a96SEric Biggers  * the filename.  Therefore, we first set up the directory's encryption key (if
6800ea87a96SEric Biggers  * not already done) and return an error if it's unavailable.
6810ea87a96SEric Biggers  *
6820ea87a96SEric Biggers  * We also verify that the link will not violate the constraint that all files
6830ea87a96SEric Biggers  * in an encrypted directory tree use the same encryption policy.
6840ea87a96SEric Biggers  *
6850ea87a96SEric Biggers  * Return: 0 on success, -ENOKEY if the directory's encryption key is missing,
686f5e55e77SEric Biggers  * -EXDEV if the link would result in an inconsistent encryption policy, or
6870ea87a96SEric Biggers  * another -errno code.
6880ea87a96SEric Biggers  */
6890ea87a96SEric Biggers static inline int fscrypt_prepare_link(struct dentry *old_dentry,
6900ea87a96SEric Biggers 				       struct inode *dir,
6910ea87a96SEric Biggers 				       struct dentry *dentry)
6920ea87a96SEric Biggers {
6930ea87a96SEric Biggers 	if (IS_ENCRYPTED(dir))
694968dd6d0SEric Biggers 		return __fscrypt_prepare_link(d_inode(old_dentry), dir, dentry);
6950ea87a96SEric Biggers 	return 0;
6960ea87a96SEric Biggers }
6970ea87a96SEric Biggers 
69894b26f36SEric Biggers /**
699d2fe9754SEric Biggers  * fscrypt_prepare_rename() - prepare for a rename between possibly-encrypted
700d2fe9754SEric Biggers  *			      directories
70194b26f36SEric Biggers  * @old_dir: source directory
70294b26f36SEric Biggers  * @old_dentry: dentry for source file
70394b26f36SEric Biggers  * @new_dir: target directory
70494b26f36SEric Biggers  * @new_dentry: dentry for target location (may be negative unless exchanging)
70594b26f36SEric Biggers  * @flags: rename flags (we care at least about %RENAME_EXCHANGE)
70694b26f36SEric Biggers  *
70794b26f36SEric Biggers  * Prepare for ->rename() where the source and/or target directories may be
70894b26f36SEric Biggers  * encrypted.  A new link can only be added to an encrypted directory if the
70994b26f36SEric Biggers  * directory's encryption key is available --- since otherwise we'd have no way
71094b26f36SEric Biggers  * to encrypt the filename.  A rename to an existing name, on the other hand,
71194b26f36SEric Biggers  * *is* cryptographically possible without the key.  However, we take the more
71294b26f36SEric Biggers  * conservative approach and just forbid all no-key renames.
71394b26f36SEric Biggers  *
71494b26f36SEric Biggers  * We also verify that the rename will not violate the constraint that all files
71594b26f36SEric Biggers  * in an encrypted directory tree use the same encryption policy.
71694b26f36SEric Biggers  *
717f5e55e77SEric Biggers  * Return: 0 on success, -ENOKEY if an encryption key is missing, -EXDEV if the
71894b26f36SEric Biggers  * rename would cause inconsistent encryption policies, or another -errno code.
71994b26f36SEric Biggers  */
72094b26f36SEric Biggers static inline int fscrypt_prepare_rename(struct inode *old_dir,
72194b26f36SEric Biggers 					 struct dentry *old_dentry,
72294b26f36SEric Biggers 					 struct inode *new_dir,
72394b26f36SEric Biggers 					 struct dentry *new_dentry,
72494b26f36SEric Biggers 					 unsigned int flags)
72594b26f36SEric Biggers {
72694b26f36SEric Biggers 	if (IS_ENCRYPTED(old_dir) || IS_ENCRYPTED(new_dir))
72794b26f36SEric Biggers 		return __fscrypt_prepare_rename(old_dir, old_dentry,
72894b26f36SEric Biggers 						new_dir, new_dentry, flags);
72994b26f36SEric Biggers 	return 0;
73094b26f36SEric Biggers }
73194b26f36SEric Biggers 
73232c3cf02SEric Biggers /**
733d2fe9754SEric Biggers  * fscrypt_prepare_lookup() - prepare to lookup a name in a possibly-encrypted
734d2fe9754SEric Biggers  *			      directory
73532c3cf02SEric Biggers  * @dir: directory being searched
73632c3cf02SEric Biggers  * @dentry: filename being looked up
737b01531dbSEric Biggers  * @fname: (output) the name to use to search the on-disk directory
73832c3cf02SEric Biggers  *
739b01531dbSEric Biggers  * Prepare for ->lookup() in a directory which may be encrypted by determining
74070fb2612SEric Biggers  * the name that will actually be used to search the directory on-disk.  If the
74170fb2612SEric Biggers  * directory's encryption key is available, then the lookup is assumed to be by
74270fb2612SEric Biggers  * plaintext name; otherwise, it is assumed to be by no-key name.
74332c3cf02SEric Biggers  *
744*bb9cd910SDaniel Rosenberg  * This will set DCACHE_NOKEY_NAME on the dentry if the lookup is by no-key
745*bb9cd910SDaniel Rosenberg  * name.  In this case the filesystem must assign the dentry a dentry_operations
746*bb9cd910SDaniel Rosenberg  * which contains fscrypt_d_revalidate (or contains a d_revalidate method that
747*bb9cd910SDaniel Rosenberg  * calls fscrypt_d_revalidate), so that the dentry will be invalidated if the
748*bb9cd910SDaniel Rosenberg  * directory's encryption key is later added.
74932c3cf02SEric Biggers  *
75070fb2612SEric Biggers  * Return: 0 on success; -ENOENT if the directory's key is unavailable but the
75170fb2612SEric Biggers  * filename isn't a valid no-key name, so a negative dentry should be created;
75270fb2612SEric Biggers  * or another -errno code.
75332c3cf02SEric Biggers  */
75432c3cf02SEric Biggers static inline int fscrypt_prepare_lookup(struct inode *dir,
75532c3cf02SEric Biggers 					 struct dentry *dentry,
756b01531dbSEric Biggers 					 struct fscrypt_name *fname)
75732c3cf02SEric Biggers {
75832c3cf02SEric Biggers 	if (IS_ENCRYPTED(dir))
759b01531dbSEric Biggers 		return __fscrypt_prepare_lookup(dir, dentry, fname);
760b01531dbSEric Biggers 
761b01531dbSEric Biggers 	memset(fname, 0, sizeof(*fname));
762b01531dbSEric Biggers 	fname->usr_fname = &dentry->d_name;
763b01531dbSEric Biggers 	fname->disk_name.name = (unsigned char *)dentry->d_name.name;
764b01531dbSEric Biggers 	fname->disk_name.len = dentry->d_name.len;
76532c3cf02SEric Biggers 	return 0;
76632c3cf02SEric Biggers }
76732c3cf02SEric Biggers 
768815dac33SEric Biggers /**
769d2fe9754SEric Biggers  * fscrypt_prepare_setattr() - prepare to change a possibly-encrypted inode's
770d2fe9754SEric Biggers  *			       attributes
771815dac33SEric Biggers  * @dentry: dentry through which the inode is being changed
772815dac33SEric Biggers  * @attr: attributes to change
773815dac33SEric Biggers  *
774815dac33SEric Biggers  * Prepare for ->setattr() on a possibly-encrypted inode.  On an encrypted file,
775815dac33SEric Biggers  * most attribute changes are allowed even without the encryption key.  However,
776815dac33SEric Biggers  * without the encryption key we do have to forbid truncates.  This is needed
777815dac33SEric Biggers  * because the size being truncated to may not be a multiple of the filesystem
778815dac33SEric Biggers  * block size, and in that case we'd have to decrypt the final block, zero the
779815dac33SEric Biggers  * portion past i_size, and re-encrypt it.  (We *could* allow truncating to a
780815dac33SEric Biggers  * filesystem block boundary, but it's simpler to just forbid all truncates ---
781815dac33SEric Biggers  * and we already forbid all other contents modifications without the key.)
782815dac33SEric Biggers  *
783815dac33SEric Biggers  * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code
784815dac33SEric Biggers  * if a problem occurred while setting up the encryption key.
785815dac33SEric Biggers  */
786815dac33SEric Biggers static inline int fscrypt_prepare_setattr(struct dentry *dentry,
787815dac33SEric Biggers 					  struct iattr *attr)
788815dac33SEric Biggers {
789815dac33SEric Biggers 	if (attr->ia_valid & ATTR_SIZE)
790815dac33SEric Biggers 		return fscrypt_require_key(d_inode(dentry));
791815dac33SEric Biggers 	return 0;
792815dac33SEric Biggers }
793815dac33SEric Biggers 
79476e81d6dSEric Biggers /**
795d2fe9754SEric Biggers  * fscrypt_encrypt_symlink() - encrypt the symlink target if needed
79676e81d6dSEric Biggers  * @inode: symlink inode
79776e81d6dSEric Biggers  * @target: plaintext symlink target
79876e81d6dSEric Biggers  * @len: length of @target excluding null terminator
79976e81d6dSEric Biggers  * @disk_link: (in/out) the on-disk symlink target being prepared
80076e81d6dSEric Biggers  *
80176e81d6dSEric Biggers  * If the symlink target needs to be encrypted, then this function encrypts it
80276e81d6dSEric Biggers  * into @disk_link->name.  fscrypt_prepare_symlink() must have been called
80376e81d6dSEric Biggers  * previously to compute @disk_link->len.  If the filesystem did not allocate a
80476e81d6dSEric Biggers  * buffer for @disk_link->name after calling fscrypt_prepare_link(), then one
80576e81d6dSEric Biggers  * will be kmalloc()'ed and the filesystem will be responsible for freeing it.
80676e81d6dSEric Biggers  *
80776e81d6dSEric Biggers  * Return: 0 on success, -errno on failure
80876e81d6dSEric Biggers  */
80976e81d6dSEric Biggers static inline int fscrypt_encrypt_symlink(struct inode *inode,
81076e81d6dSEric Biggers 					  const char *target,
81176e81d6dSEric Biggers 					  unsigned int len,
81276e81d6dSEric Biggers 					  struct fscrypt_str *disk_link)
81376e81d6dSEric Biggers {
81476e81d6dSEric Biggers 	if (IS_ENCRYPTED(inode))
81576e81d6dSEric Biggers 		return __fscrypt_encrypt_symlink(inode, target, len, disk_link);
81676e81d6dSEric Biggers 	return 0;
81776e81d6dSEric Biggers }
81876e81d6dSEric Biggers 
819d2d0727bSEric Biggers /* If *pagep is a bounce page, free it and set *pagep to the pagecache page */
820d2d0727bSEric Biggers static inline void fscrypt_finalize_bounce_page(struct page **pagep)
821d2d0727bSEric Biggers {
822d2d0727bSEric Biggers 	struct page *page = *pagep;
823d2d0727bSEric Biggers 
824d2d0727bSEric Biggers 	if (fscrypt_is_bounce_page(page)) {
825d2d0727bSEric Biggers 		*pagep = fscrypt_pagecache_page(page);
826d2d0727bSEric Biggers 		fscrypt_free_bounce_page(page);
827d2d0727bSEric Biggers 	}
828d2d0727bSEric Biggers }
829d2d0727bSEric Biggers 
830734f0d24SDave Chinner #endif	/* _LINUX_FSCRYPT_H */
831