fscrypt: new helper function - fscrypt_prepare_link()
[linux-block.git] / include / linux / fscrypt.h
CommitLineData
46f47e48 1/*
734f0d24
DC
2 * fscrypt.h: declarations for per-file encryption
3 *
4 * Filesystems that implement per-file encryption include this header
5 * file with the __FS_HAS_ENCRYPTION set according to whether that filesystem
6 * is being built with encryption support or not.
46f47e48
EB
7 *
8 * Copyright (C) 2015, Google, Inc.
9 *
10 * Written by Michael Halcrow, 2015.
11 * Modified by Jaegeuk Kim, 2015.
12 */
734f0d24
DC
13#ifndef _LINUX_FSCRYPT_H
14#define _LINUX_FSCRYPT_H
46f47e48
EB
15
16#include <linux/key.h>
17#include <linux/fs.h>
18#include <linux/mm.h>
19#include <linux/bio.h>
20#include <linux/dcache.h>
21#include <crypto/skcipher.h>
22#include <uapi/linux/fs.h>
23
24#define FS_CRYPTO_BLOCK_SIZE 16
25
26struct fscrypt_info;
27
28struct fscrypt_ctx {
29 union {
30 struct {
31 struct page *bounce_page; /* Ciphertext page */
32 struct page *control_page; /* Original page */
33 } w;
34 struct {
35 struct bio *bio;
36 struct work_struct work;
37 } r;
38 struct list_head free_list; /* Free list */
39 };
40 u8 flags; /* Flags */
41};
42
43/**
44 * For encrypted symlinks, the ciphertext length is stored at the beginning
45 * of the string in little-endian format.
46 */
47struct fscrypt_symlink_data {
48 __le16 len;
49 char encrypted_path[1];
50} __packed;
51
46f47e48
EB
52struct fscrypt_str {
53 unsigned char *name;
54 u32 len;
55};
56
57struct fscrypt_name {
58 const struct qstr *usr_fname;
59 struct fscrypt_str disk_name;
60 u32 hash;
61 u32 minor_hash;
62 struct fscrypt_str crypto_buf;
63};
64
65#define FSTR_INIT(n, l) { .name = n, .len = l }
66#define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len)
67#define fname_name(p) ((p)->disk_name.name)
68#define fname_len(p) ((p)->disk_name.len)
69
70/*
71 * fscrypt superblock flags
72 */
73#define FS_CFLG_OWN_PAGES (1U << 1)
74
75/*
76 * crypto opertions for filesystems
77 */
78struct fscrypt_operations {
79 unsigned int flags;
80 const char *key_prefix;
81 int (*get_context)(struct inode *, void *, size_t);
46f47e48 82 int (*set_context)(struct inode *, const void *, size_t, void *);
c250b7dd 83 bool (*dummy_context)(struct inode *);
46f47e48
EB
84 bool (*empty_dir)(struct inode *);
85 unsigned (*max_namelen)(struct inode *);
86};
87
af65207c
TE
88/* Maximum value for the third parameter of fscrypt_operations.set_context(). */
89#define FSCRYPT_SET_CONTEXT_MAX_SIZE 28
90
46f47e48
EB
91static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
92{
93 if (inode->i_sb->s_cop->dummy_context &&
94 inode->i_sb->s_cop->dummy_context(inode))
95 return true;
96 return false;
97}
98
b7e7cf7a
DW
99static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
100 u32 filenames_mode)
46f47e48 101{
b7e7cf7a
DW
102 if (contents_mode == FS_ENCRYPTION_MODE_AES_128_CBC &&
103 filenames_mode == FS_ENCRYPTION_MODE_AES_128_CTS)
104 return true;
46f47e48 105
b7e7cf7a
DW
106 if (contents_mode == FS_ENCRYPTION_MODE_AES_256_XTS &&
107 filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
108 return true;
109
110 return false;
46f47e48
EB
111}
112
113static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
114{
115 if (str->len == 1 && str->name[0] == '.')
116 return true;
117
118 if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
119 return true;
120
121 return false;
122}
123
734f0d24
DC
124#if __FS_HAS_ENCRYPTION
125
46f47e48
EB
126static inline struct page *fscrypt_control_page(struct page *page)
127{
46f47e48 128 return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
734f0d24
DC
129}
130
131static inline bool fscrypt_has_encryption_key(const struct inode *inode)
132{
133 return (inode->i_crypt_info != NULL);
134}
135
136#include <linux/fscrypt_supp.h>
137
138#else /* !__FS_HAS_ENCRYPTION */
139
140static inline struct page *fscrypt_control_page(struct page *page)
141{
46f47e48
EB
142 WARN_ON_ONCE(1);
143 return ERR_PTR(-EINVAL);
46f47e48
EB
144}
145
734f0d24 146static inline bool fscrypt_has_encryption_key(const struct inode *inode)
46f47e48 147{
46f47e48 148 return 0;
46f47e48
EB
149}
150
734f0d24
DC
151#include <linux/fscrypt_notsupp.h>
152#endif /* __FS_HAS_ENCRYPTION */
153
d293c3e4
EB
154/**
155 * fscrypt_require_key - require an inode's encryption key
156 * @inode: the inode we need the key for
157 *
158 * If the inode is encrypted, set up its encryption key if not already done.
159 * Then require that the key be present and return -ENOKEY otherwise.
160 *
161 * No locks are needed, and the key will live as long as the struct inode --- so
162 * it won't go away from under you.
163 *
164 * Return: 0 on success, -ENOKEY if the key is missing, or another -errno code
165 * if a problem occurred while setting up the encryption key.
166 */
167static inline int fscrypt_require_key(struct inode *inode)
168{
169 if (IS_ENCRYPTED(inode)) {
170 int err = fscrypt_get_encryption_info(inode);
171
172 if (err)
173 return err;
174 if (!fscrypt_has_encryption_key(inode))
175 return -ENOKEY;
176 }
177 return 0;
178}
734f0d24 179
0ea87a96
EB
180/**
181 * fscrypt_prepare_link - prepare to link an inode into a possibly-encrypted directory
182 * @old_dentry: an existing dentry for the inode being linked
183 * @dir: the target directory
184 * @dentry: negative dentry for the target filename
185 *
186 * A new link can only be added to an encrypted directory if the directory's
187 * encryption key is available --- since otherwise we'd have no way to encrypt
188 * the filename. Therefore, we first set up the directory's encryption key (if
189 * not already done) and return an error if it's unavailable.
190 *
191 * We also verify that the link will not violate the constraint that all files
192 * in an encrypted directory tree use the same encryption policy.
193 *
194 * Return: 0 on success, -ENOKEY if the directory's encryption key is missing,
195 * -EPERM if the link would result in an inconsistent encryption policy, or
196 * another -errno code.
197 */
198static inline int fscrypt_prepare_link(struct dentry *old_dentry,
199 struct inode *dir,
200 struct dentry *dentry)
201{
202 if (IS_ENCRYPTED(dir))
203 return __fscrypt_prepare_link(d_inode(old_dentry), dir);
204 return 0;
205}
206
734f0d24 207#endif /* _LINUX_FSCRYPT_H */