Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * This contains functions for filename crypto management
4 : : *
5 : : * Copyright (C) 2015, Google, Inc.
6 : : * Copyright (C) 2015, Motorola Mobility
7 : : *
8 : : * Written by Uday Savagaonkar, 2014.
9 : : * Modified by Jaegeuk Kim, 2015.
10 : : *
11 : : * This has not yet undergone a rigorous security audit.
12 : : */
13 : :
14 : : #include <linux/scatterlist.h>
15 : : #include <crypto/skcipher.h>
16 : : #include "fscrypt_private.h"
17 : :
18 : 0 : static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
19 : : {
20 [ # # # # ]: 0 : if (str->len == 1 && str->name[0] == '.')
21 : : return true;
22 : :
23 [ # # # # : 0 : if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
# # ]
24 : : return true;
25 : :
26 : 0 : return false;
27 : : }
28 : :
29 : : /**
30 : : * fname_encrypt() - encrypt a filename
31 : : *
32 : : * The output buffer must be at least as large as the input buffer.
33 : : * Any extra space is filled with NUL padding before encryption.
34 : : *
35 : : * Return: 0 on success, -errno on failure
36 : : */
37 : 0 : int fname_encrypt(struct inode *inode, const struct qstr *iname,
38 : : u8 *out, unsigned int olen)
39 : : {
40 : : struct skcipher_request *req = NULL;
41 : 0 : DECLARE_CRYPTO_WAIT(wait);
42 : 0 : struct fscrypt_info *ci = inode->i_crypt_info;
43 : 0 : struct crypto_skcipher *tfm = ci->ci_ctfm;
44 : : union fscrypt_iv iv;
45 : : struct scatterlist sg;
46 : : int res;
47 : :
48 : : /*
49 : : * Copy the filename to the output buffer for encrypting in-place and
50 : : * pad it with the needed number of NUL bytes.
51 : : */
52 [ # # # # ]: 0 : if (WARN_ON(olen < iname->len))
53 : : return -ENOBUFS;
54 : 0 : memcpy(out, iname->name, iname->len);
55 : 0 : memset(out + iname->len, 0, olen - iname->len);
56 : :
57 : : /* Initialize the IV */
58 : 0 : fscrypt_generate_iv(&iv, 0, ci);
59 : :
60 : : /* Set up the encryption request */
61 : 0 : req = skcipher_request_alloc(tfm, GFP_NOFS);
62 [ # # ]: 0 : if (!req)
63 : : return -ENOMEM;
64 : : skcipher_request_set_callback(req,
65 : : CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
66 : : crypto_req_done, &wait);
67 : 0 : sg_init_one(&sg, out, olen);
68 : : skcipher_request_set_crypt(req, &sg, &sg, olen, &iv);
69 : :
70 : : /* Do the encryption */
71 : 0 : res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
72 : : skcipher_request_free(req);
73 [ # # ]: 0 : if (res < 0) {
74 : 0 : fscrypt_err(inode, "Filename encryption failed: %d", res);
75 : 0 : return res;
76 : : }
77 : :
78 : : return 0;
79 : : }
80 : :
81 : : /**
82 : : * fname_decrypt() - decrypt a filename
83 : : *
84 : : * The caller must have allocated sufficient memory for the @oname string.
85 : : *
86 : : * Return: 0 on success, -errno on failure
87 : : */
88 : 0 : static int fname_decrypt(struct inode *inode,
89 : : const struct fscrypt_str *iname,
90 : : struct fscrypt_str *oname)
91 : : {
92 : : struct skcipher_request *req = NULL;
93 : 0 : DECLARE_CRYPTO_WAIT(wait);
94 : : struct scatterlist src_sg, dst_sg;
95 : 0 : struct fscrypt_info *ci = inode->i_crypt_info;
96 : 0 : struct crypto_skcipher *tfm = ci->ci_ctfm;
97 : : union fscrypt_iv iv;
98 : : int res;
99 : :
100 : : /* Allocate request */
101 : 0 : req = skcipher_request_alloc(tfm, GFP_NOFS);
102 [ # # ]: 0 : if (!req)
103 : : return -ENOMEM;
104 : : skcipher_request_set_callback(req,
105 : : CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
106 : : crypto_req_done, &wait);
107 : :
108 : : /* Initialize IV */
109 : 0 : fscrypt_generate_iv(&iv, 0, ci);
110 : :
111 : : /* Create decryption request */
112 : 0 : sg_init_one(&src_sg, iname->name, iname->len);
113 : 0 : sg_init_one(&dst_sg, oname->name, oname->len);
114 : 0 : skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, &iv);
115 : 0 : res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
116 : : skcipher_request_free(req);
117 [ # # ]: 0 : if (res < 0) {
118 : 0 : fscrypt_err(inode, "Filename decryption failed: %d", res);
119 : 0 : return res;
120 : : }
121 : :
122 : 0 : oname->len = strnlen(oname->name, iname->len);
123 : 0 : return 0;
124 : : }
125 : :
126 : : static const char lookup_table[65] =
127 : : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
128 : :
129 : : #define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
130 : :
131 : : /**
132 : : * base64_encode() -
133 : : *
134 : : * Encodes the input string using characters from the set [A-Za-z0-9+,].
135 : : * The encoded string is roughly 4/3 times the size of the input string.
136 : : *
137 : : * Return: length of the encoded string
138 : : */
139 : 0 : static int base64_encode(const u8 *src, int len, char *dst)
140 : : {
141 : : int i, bits = 0, ac = 0;
142 : : char *cp = dst;
143 : :
144 [ # # ]: 0 : for (i = 0; i < len; i++) {
145 : 0 : ac += src[i] << bits;
146 : 0 : bits += 8;
147 : : do {
148 : 0 : *cp++ = lookup_table[ac & 0x3f];
149 : 0 : ac >>= 6;
150 : 0 : bits -= 6;
151 [ # # ]: 0 : } while (bits >= 6);
152 : : }
153 [ # # ]: 0 : if (bits)
154 : 0 : *cp++ = lookup_table[ac & 0x3f];
155 : 0 : return cp - dst;
156 : : }
157 : :
158 : 0 : static int base64_decode(const char *src, int len, u8 *dst)
159 : : {
160 : : int i, bits = 0, ac = 0;
161 : : const char *p;
162 : : u8 *cp = dst;
163 : :
164 [ # # ]: 0 : for (i = 0; i < len; i++) {
165 : 0 : p = strchr(lookup_table, src[i]);
166 [ # # # # ]: 0 : if (p == NULL || src[i] == 0)
167 : : return -2;
168 : 0 : ac += (p - lookup_table) << bits;
169 : 0 : bits += 6;
170 [ # # ]: 0 : if (bits >= 8) {
171 : 0 : *cp++ = ac & 0xff;
172 : 0 : ac >>= 8;
173 : 0 : bits -= 8;
174 : : }
175 : : }
176 [ # # ]: 0 : if (ac)
177 : : return -1;
178 : 0 : return cp - dst;
179 : : }
180 : :
181 : 0 : bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
182 : : u32 max_len, u32 *encrypted_len_ret)
183 : : {
184 : 0 : const struct fscrypt_info *ci = inode->i_crypt_info;
185 : 0 : int padding = 4 << (fscrypt_policy_flags(&ci->ci_policy) &
186 : : FSCRYPT_POLICY_FLAGS_PAD_MASK);
187 : : u32 encrypted_len;
188 : :
189 [ # # ]: 0 : if (orig_len > max_len)
190 : : return false;
191 : 0 : encrypted_len = max(orig_len, (u32)FS_CRYPTO_BLOCK_SIZE);
192 : 0 : encrypted_len = round_up(encrypted_len, padding);
193 : 0 : *encrypted_len_ret = min(encrypted_len, max_len);
194 : 0 : return true;
195 : : }
196 : :
197 : : /**
198 : : * fscrypt_fname_alloc_buffer - allocate a buffer for presented filenames
199 : : *
200 : : * Allocate a buffer that is large enough to hold any decrypted or encoded
201 : : * filename (null-terminated), for the given maximum encrypted filename length.
202 : : *
203 : : * Return: 0 on success, -errno on failure
204 : : */
205 : 0 : int fscrypt_fname_alloc_buffer(const struct inode *inode,
206 : : u32 max_encrypted_len,
207 : : struct fscrypt_str *crypto_str)
208 : : {
209 : : const u32 max_encoded_len =
210 : : max_t(u32, BASE64_CHARS(FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE),
211 : : 1 + BASE64_CHARS(sizeof(struct fscrypt_digested_name)));
212 : : u32 max_presented_len;
213 : :
214 : 0 : max_presented_len = max(max_encoded_len, max_encrypted_len);
215 : :
216 : 0 : crypto_str->name = kmalloc(max_presented_len + 1, GFP_NOFS);
217 [ # # ]: 0 : if (!crypto_str->name)
218 : : return -ENOMEM;
219 : 0 : crypto_str->len = max_presented_len;
220 : 0 : return 0;
221 : : }
222 : : EXPORT_SYMBOL(fscrypt_fname_alloc_buffer);
223 : :
224 : : /**
225 : : * fscrypt_fname_free_buffer - free the buffer for presented filenames
226 : : *
227 : : * Free the buffer allocated by fscrypt_fname_alloc_buffer().
228 : : */
229 : 954094 : void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
230 : : {
231 [ + - ]: 954094 : if (!crypto_str)
232 : 954094 : return;
233 : 954094 : kfree(crypto_str->name);
234 : 954094 : crypto_str->name = NULL;
235 : : }
236 : : EXPORT_SYMBOL(fscrypt_fname_free_buffer);
237 : :
238 : : /**
239 : : * fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
240 : : * space
241 : : *
242 : : * The caller must have allocated sufficient memory for the @oname string.
243 : : *
244 : : * If the key is available, we'll decrypt the disk name; otherwise, we'll encode
245 : : * it for presentation. Short names are directly base64-encoded, while long
246 : : * names are encoded in fscrypt_digested_name format.
247 : : *
248 : : * Return: 0 on success, -errno on failure
249 : : */
250 : 0 : int fscrypt_fname_disk_to_usr(struct inode *inode,
251 : : u32 hash, u32 minor_hash,
252 : : const struct fscrypt_str *iname,
253 : : struct fscrypt_str *oname)
254 : : {
255 : 0 : const struct qstr qname = FSTR_TO_QSTR(iname);
256 : : struct fscrypt_digested_name digested_name;
257 : :
258 [ # # ]: 0 : if (fscrypt_is_dot_dotdot(&qname)) {
259 : 0 : oname->name[0] = '.';
260 : 0 : oname->name[iname->len - 1] = '.';
261 : 0 : oname->len = iname->len;
262 : 0 : return 0;
263 : : }
264 : :
265 [ # # ]: 0 : if (iname->len < FS_CRYPTO_BLOCK_SIZE)
266 : : return -EUCLEAN;
267 : :
268 [ # # ]: 0 : if (fscrypt_has_encryption_key(inode))
269 : 0 : return fname_decrypt(inode, iname, oname);
270 : :
271 [ # # ]: 0 : if (iname->len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE) {
272 : 0 : oname->len = base64_encode(iname->name, iname->len,
273 : 0 : oname->name);
274 : 0 : return 0;
275 : : }
276 [ # # ]: 0 : if (hash) {
277 : 0 : digested_name.hash = hash;
278 : 0 : digested_name.minor_hash = minor_hash;
279 : : } else {
280 : 0 : digested_name.hash = 0;
281 : 0 : digested_name.minor_hash = 0;
282 : : }
283 : 0 : memcpy(digested_name.digest,
284 : 0 : FSCRYPT_FNAME_DIGEST(iname->name, iname->len),
285 : : FSCRYPT_FNAME_DIGEST_SIZE);
286 : 0 : oname->name[0] = '_';
287 : 0 : oname->len = 1 + base64_encode((const u8 *)&digested_name,
288 : 0 : sizeof(digested_name), oname->name + 1);
289 : 0 : return 0;
290 : : }
291 : : EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
292 : :
293 : : /**
294 : : * fscrypt_setup_filename() - prepare to search a possibly encrypted directory
295 : : * @dir: the directory that will be searched
296 : : * @iname: the user-provided filename being searched for
297 : : * @lookup: 1 if we're allowed to proceed without the key because it's
298 : : * ->lookup() or we're finding the dir_entry for deletion; 0 if we cannot
299 : : * proceed without the key because we're going to create the dir_entry.
300 : : * @fname: the filename information to be filled in
301 : : *
302 : : * Given a user-provided filename @iname, this function sets @fname->disk_name
303 : : * to the name that would be stored in the on-disk directory entry, if possible.
304 : : * If the directory is unencrypted this is simply @iname. Else, if we have the
305 : : * directory's encryption key, then @iname is the plaintext, so we encrypt it to
306 : : * get the disk_name.
307 : : *
308 : : * Else, for keyless @lookup operations, @iname is the presented ciphertext, so
309 : : * we decode it to get either the ciphertext disk_name (for short names) or the
310 : : * fscrypt_digested_name (for long names). Non-@lookup operations will be
311 : : * impossible in this case, so we fail them with ENOKEY.
312 : : *
313 : : * If successful, fscrypt_free_filename() must be called later to clean up.
314 : : *
315 : : * Return: 0 on success, -errno on failure
316 : : */
317 : 248950 : int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
318 : : int lookup, struct fscrypt_name *fname)
319 : : {
320 : : int ret;
321 : : int digested;
322 : :
323 : 248950 : memset(fname, 0, sizeof(struct fscrypt_name));
324 : 248950 : fname->usr_fname = iname;
325 : :
326 [ - + # # ]: 248950 : if (!IS_ENCRYPTED(dir) || fscrypt_is_dot_dotdot(iname)) {
327 : 248950 : fname->disk_name.name = (unsigned char *)iname->name;
328 : 248950 : fname->disk_name.len = iname->len;
329 : 248950 : return 0;
330 : : }
331 : 0 : ret = fscrypt_get_encryption_info(dir);
332 [ # # ]: 0 : if (ret)
333 : : return ret;
334 : :
335 [ # # ]: 0 : if (fscrypt_has_encryption_key(dir)) {
336 [ # # ]: 0 : if (!fscrypt_fname_encrypted_size(dir, iname->len,
337 : 0 : dir->i_sb->s_cop->max_namelen,
338 : : &fname->crypto_buf.len))
339 : : return -ENAMETOOLONG;
340 : 0 : fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
341 : : GFP_NOFS);
342 [ # # ]: 0 : if (!fname->crypto_buf.name)
343 : : return -ENOMEM;
344 : :
345 : 0 : ret = fname_encrypt(dir, iname, fname->crypto_buf.name,
346 : : fname->crypto_buf.len);
347 [ # # ]: 0 : if (ret)
348 : : goto errout;
349 : 0 : fname->disk_name.name = fname->crypto_buf.name;
350 : 0 : fname->disk_name.len = fname->crypto_buf.len;
351 : 0 : return 0;
352 : : }
353 [ # # ]: 0 : if (!lookup)
354 : : return -ENOKEY;
355 : 0 : fname->is_ciphertext_name = true;
356 : :
357 : : /*
358 : : * We don't have the key and we are doing a lookup; decode the
359 : : * user-supplied name
360 : : */
361 [ # # ]: 0 : if (iname->name[0] == '_') {
362 [ # # ]: 0 : if (iname->len !=
363 : : 1 + BASE64_CHARS(sizeof(struct fscrypt_digested_name)))
364 : : return -ENOENT;
365 : : digested = 1;
366 : : } else {
367 [ # # ]: 0 : if (iname->len >
368 : : BASE64_CHARS(FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE))
369 : : return -ENOENT;
370 : : digested = 0;
371 : : }
372 : :
373 : 0 : fname->crypto_buf.name =
374 : : kmalloc(max_t(size_t, FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE,
375 : : sizeof(struct fscrypt_digested_name)),
376 : : GFP_KERNEL);
377 [ # # ]: 0 : if (fname->crypto_buf.name == NULL)
378 : : return -ENOMEM;
379 : :
380 : 0 : ret = base64_decode(iname->name + digested, iname->len - digested,
381 : : fname->crypto_buf.name);
382 [ # # ]: 0 : if (ret < 0) {
383 : : ret = -ENOENT;
384 : : goto errout;
385 : : }
386 : 0 : fname->crypto_buf.len = ret;
387 [ # # ]: 0 : if (digested) {
388 : 0 : const struct fscrypt_digested_name *n =
389 : : (const void *)fname->crypto_buf.name;
390 : 0 : fname->hash = n->hash;
391 : 0 : fname->minor_hash = n->minor_hash;
392 : : } else {
393 : 0 : fname->disk_name.name = fname->crypto_buf.name;
394 : 0 : fname->disk_name.len = fname->crypto_buf.len;
395 : : }
396 : : return 0;
397 : :
398 : : errout:
399 : 0 : kfree(fname->crypto_buf.name);
400 : 0 : return ret;
401 : : }
402 : : EXPORT_SYMBOL(fscrypt_setup_filename);
|