2 * linux/fs/f2fs/crypto_fname.c
4 * Copied from linux/fs/ext4/crypto.c
6 * Copyright (C) 2015, Google, Inc.
7 * Copyright (C) 2015, Motorola Mobility
9 * This contains functions for filename crypto management in f2fs
11 * Written by Uday Savagaonkar, 2014.
13 * Adjust f2fs dentry structure
16 * This has not yet undergone a rigorous security audit.
18 #include <crypto/hash.h>
19 #include <crypto/sha.h>
20 #include <keys/encrypted-type.h>
21 #include <keys/user-type.h>
22 #include <linux/crypto.h>
23 #include <linux/gfp.h>
24 #include <linux/kernel.h>
25 #include <linux/key.h>
26 #include <linux/list.h>
27 #include <linux/mempool.h>
28 #include <linux/random.h>
29 #include <linux/scatterlist.h>
30 #include <linux/spinlock_types.h>
31 #include <linux/f2fs_fs.h>
32 #include <linux/ratelimit.h>
35 #include "f2fs_crypto.h"
39 * f2fs_dir_crypt_complete() -
41 static void f2fs_dir_crypt_complete(struct crypto_async_request
*req
, int res
)
43 struct f2fs_completion_result
*ecr
= req
->data
;
45 if (res
== -EINPROGRESS
)
48 complete(&ecr
->completion
);
51 bool f2fs_valid_filenames_enc_mode(uint32_t mode
)
53 return (mode
== F2FS_ENCRYPTION_MODE_AES_256_CTS
);
56 static unsigned max_name_len(struct inode
*inode
)
58 return S_ISLNK(inode
->i_mode
) ? inode
->i_sb
->s_blocksize
:
63 * f2fs_fname_encrypt() -
65 * This function encrypts the input filename, and returns the length of the
66 * ciphertext. Errors are returned as negative numbers. We trust the caller to
67 * allocate sufficient memory to oname string.
69 static int f2fs_fname_encrypt(struct inode
*inode
,
70 const struct qstr
*iname
, struct f2fs_str
*oname
)
73 struct ablkcipher_request
*req
= NULL
;
74 DECLARE_F2FS_COMPLETION_RESULT(ecr
);
75 struct f2fs_crypt_info
*ci
= F2FS_I(inode
)->i_crypt_info
;
76 struct crypto_ablkcipher
*tfm
= ci
->ci_ctfm
;
78 char iv
[F2FS_CRYPTO_BLOCK_SIZE
];
79 struct scatterlist src_sg
, dst_sg
;
80 int padding
= 4 << (ci
->ci_flags
& F2FS_POLICY_FLAGS_PAD_MASK
);
81 char *workbuf
, buf
[32], *alloc_buf
= NULL
;
82 unsigned lim
= max_name_len(inode
);
84 if (iname
->len
<= 0 || iname
->len
> lim
)
87 ciphertext_len
= (iname
->len
< F2FS_CRYPTO_BLOCK_SIZE
) ?
88 F2FS_CRYPTO_BLOCK_SIZE
: iname
->len
;
89 ciphertext_len
= f2fs_fname_crypto_round_up(ciphertext_len
, padding
);
90 ciphertext_len
= (ciphertext_len
> lim
) ? lim
: ciphertext_len
;
92 if (ciphertext_len
<= sizeof(buf
)) {
95 alloc_buf
= kmalloc(ciphertext_len
, GFP_NOFS
);
101 /* Allocate request */
102 req
= ablkcipher_request_alloc(tfm
, GFP_NOFS
);
104 printk_ratelimited(KERN_ERR
105 "%s: crypto_request_alloc() failed\n", __func__
);
109 ablkcipher_request_set_callback(req
,
110 CRYPTO_TFM_REQ_MAY_BACKLOG
| CRYPTO_TFM_REQ_MAY_SLEEP
,
111 f2fs_dir_crypt_complete
, &ecr
);
114 memcpy(workbuf
, iname
->name
, iname
->len
);
115 if (iname
->len
< ciphertext_len
)
116 memset(workbuf
+ iname
->len
, 0, ciphertext_len
- iname
->len
);
119 memset(iv
, 0, F2FS_CRYPTO_BLOCK_SIZE
);
121 /* Create encryption request */
122 sg_init_one(&src_sg
, workbuf
, ciphertext_len
);
123 sg_init_one(&dst_sg
, oname
->name
, ciphertext_len
);
124 ablkcipher_request_set_crypt(req
, &src_sg
, &dst_sg
, ciphertext_len
, iv
);
125 res
= crypto_ablkcipher_encrypt(req
);
126 if (res
== -EINPROGRESS
|| res
== -EBUSY
) {
127 BUG_ON(req
->base
.data
!= &ecr
);
128 wait_for_completion(&ecr
.completion
);
132 ablkcipher_request_free(req
);
134 printk_ratelimited(KERN_ERR
135 "%s: Error (error code %d)\n", __func__
, res
);
137 oname
->len
= ciphertext_len
;
142 * f2fs_fname_decrypt()
143 * This function decrypts the input filename, and returns
144 * the length of the plaintext.
145 * Errors are returned as negative numbers.
146 * We trust the caller to allocate sufficient memory to oname string.
148 static int f2fs_fname_decrypt(struct inode
*inode
,
149 const struct f2fs_str
*iname
, struct f2fs_str
*oname
)
151 struct ablkcipher_request
*req
= NULL
;
152 DECLARE_F2FS_COMPLETION_RESULT(ecr
);
153 struct scatterlist src_sg
, dst_sg
;
154 struct f2fs_crypt_info
*ci
= F2FS_I(inode
)->i_crypt_info
;
155 struct crypto_ablkcipher
*tfm
= ci
->ci_ctfm
;
157 char iv
[F2FS_CRYPTO_BLOCK_SIZE
];
158 unsigned lim
= max_name_len(inode
);
160 if (iname
->len
<= 0 || iname
->len
> lim
)
163 /* Allocate request */
164 req
= ablkcipher_request_alloc(tfm
, GFP_NOFS
);
166 printk_ratelimited(KERN_ERR
167 "%s: crypto_request_alloc() failed\n", __func__
);
170 ablkcipher_request_set_callback(req
,
171 CRYPTO_TFM_REQ_MAY_BACKLOG
| CRYPTO_TFM_REQ_MAY_SLEEP
,
172 f2fs_dir_crypt_complete
, &ecr
);
175 memset(iv
, 0, F2FS_CRYPTO_BLOCK_SIZE
);
177 /* Create decryption request */
178 sg_init_one(&src_sg
, iname
->name
, iname
->len
);
179 sg_init_one(&dst_sg
, oname
->name
, oname
->len
);
180 ablkcipher_request_set_crypt(req
, &src_sg
, &dst_sg
, iname
->len
, iv
);
181 res
= crypto_ablkcipher_decrypt(req
);
182 if (res
== -EINPROGRESS
|| res
== -EBUSY
) {
183 BUG_ON(req
->base
.data
!= &ecr
);
184 wait_for_completion(&ecr
.completion
);
187 ablkcipher_request_free(req
);
189 printk_ratelimited(KERN_ERR
190 "%s: Error in f2fs_fname_decrypt (error code %d)\n",
195 oname
->len
= strnlen(oname
->name
, iname
->len
);
199 static const char *lookup_table
=
200 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
203 * f2fs_fname_encode_digest() -
205 * Encodes the input digest using characters from the set [a-zA-Z0-9_+].
206 * The encoded string is roughly 4/3 times the size of the input string.
208 static int digest_encode(const char *src
, int len
, char *dst
)
210 int i
= 0, bits
= 0, ac
= 0;
214 ac
+= (((unsigned char) src
[i
]) << bits
);
217 *cp
++ = lookup_table
[ac
& 0x3f];
224 *cp
++ = lookup_table
[ac
& 0x3f];
228 static int digest_decode(const char *src
, int len
, char *dst
)
230 int i
= 0, bits
= 0, ac
= 0;
235 p
= strchr(lookup_table
, src
[i
]);
236 if (p
== NULL
|| src
[i
] == 0)
238 ac
+= (p
- lookup_table
) << bits
;
253 * f2fs_fname_crypto_round_up() -
255 * Return: The next multiple of block size
257 u32
f2fs_fname_crypto_round_up(u32 size
, u32 blksize
)
259 return ((size
+ blksize
- 1) / blksize
) * blksize
;
263 * f2fs_fname_crypto_alloc_obuff() -
265 * Allocates an output buffer that is sufficient for the crypto operation
266 * specified by the context and the direction.
268 int f2fs_fname_crypto_alloc_buffer(struct inode
*inode
,
269 u32 ilen
, struct f2fs_str
*crypto_str
)
273 struct f2fs_crypt_info
*ci
= F2FS_I(inode
)->i_crypt_info
;
276 padding
= 4 << (ci
->ci_flags
& F2FS_POLICY_FLAGS_PAD_MASK
);
277 if (padding
< F2FS_CRYPTO_BLOCK_SIZE
)
278 padding
= F2FS_CRYPTO_BLOCK_SIZE
;
279 olen
= f2fs_fname_crypto_round_up(ilen
, padding
);
280 crypto_str
->len
= olen
;
281 if (olen
< F2FS_FNAME_CRYPTO_DIGEST_SIZE
* 2)
282 olen
= F2FS_FNAME_CRYPTO_DIGEST_SIZE
* 2;
283 /* Allocated buffer can hold one more character to null-terminate the
285 crypto_str
->name
= kmalloc(olen
+ 1, GFP_NOFS
);
286 if (!(crypto_str
->name
))
292 * f2fs_fname_crypto_free_buffer() -
294 * Frees the buffer allocated for crypto operation.
296 void f2fs_fname_crypto_free_buffer(struct f2fs_str
*crypto_str
)
300 kfree(crypto_str
->name
);
301 crypto_str
->name
= NULL
;
305 * f2fs_fname_disk_to_usr() - converts a filename from disk space to user space
307 int f2fs_fname_disk_to_usr(struct inode
*inode
,
309 const struct f2fs_str
*iname
,
310 struct f2fs_str
*oname
)
312 const struct qstr qname
= FSTR_TO_QSTR(iname
);
316 if (is_dot_dotdot(&qname
)) {
317 oname
->name
[0] = '.';
318 oname
->name
[iname
->len
- 1] = '.';
319 oname
->len
= iname
->len
;
323 if (F2FS_I(inode
)->i_crypt_info
)
324 return f2fs_fname_decrypt(inode
, iname
, oname
);
326 if (iname
->len
<= F2FS_FNAME_CRYPTO_DIGEST_SIZE
) {
327 ret
= digest_encode(iname
->name
, iname
->len
, oname
->name
);
332 memcpy(buf
, hash
, 4);
333 memset(buf
+ 4, 0, 4);
336 memcpy(buf
+ 8, iname
->name
+ iname
->len
- 16, 16);
337 oname
->name
[0] = '_';
338 ret
= digest_encode(buf
, 24, oname
->name
+ 1);
339 oname
->len
= ret
+ 1;
344 * f2fs_fname_usr_to_disk() - converts a filename from user space to disk space
346 int f2fs_fname_usr_to_disk(struct inode
*inode
,
347 const struct qstr
*iname
,
348 struct f2fs_str
*oname
)
351 struct f2fs_crypt_info
*ci
= F2FS_I(inode
)->i_crypt_info
;
353 if (is_dot_dotdot(iname
)) {
354 oname
->name
[0] = '.';
355 oname
->name
[iname
->len
- 1] = '.';
356 oname
->len
= iname
->len
;
361 res
= f2fs_fname_encrypt(inode
, iname
, oname
);
364 /* Without a proper key, a user is not allowed to modify the filenames
365 * in a directory. Consequently, a user space name cannot be mapped to
366 * a disk-space name */
370 int f2fs_fname_setup_filename(struct inode
*dir
, const struct qstr
*iname
,
371 int lookup
, struct f2fs_filename
*fname
)
373 struct f2fs_crypt_info
*ci
;
374 int ret
= 0, bigname
= 0;
376 memset(fname
, 0, sizeof(struct f2fs_filename
));
377 fname
->usr_fname
= iname
;
379 if (!f2fs_encrypted_inode(dir
) || is_dot_dotdot(iname
)) {
380 fname
->disk_name
.name
= (unsigned char *)iname
->name
;
381 fname
->disk_name
.len
= iname
->len
;
384 ret
= f2fs_get_encryption_info(dir
);
387 ci
= F2FS_I(dir
)->i_crypt_info
;
389 ret
= f2fs_fname_crypto_alloc_buffer(dir
, iname
->len
,
393 ret
= f2fs_fname_encrypt(dir
, iname
, &fname
->crypto_buf
);
396 fname
->disk_name
.name
= fname
->crypto_buf
.name
;
397 fname
->disk_name
.len
= fname
->crypto_buf
.len
;
403 /* We don't have the key and we are doing a lookup; decode the
406 if (iname
->name
[0] == '_')
408 if ((bigname
&& (iname
->len
!= 33)) ||
409 (!bigname
&& (iname
->len
> 43)))
412 fname
->crypto_buf
.name
= kmalloc(32, GFP_KERNEL
);
413 if (fname
->crypto_buf
.name
== NULL
)
415 ret
= digest_decode(iname
->name
+ bigname
, iname
->len
- bigname
,
416 fname
->crypto_buf
.name
);
421 fname
->crypto_buf
.len
= ret
;
423 memcpy(&fname
->hash
, fname
->crypto_buf
.name
, 4);
425 fname
->disk_name
.name
= fname
->crypto_buf
.name
;
426 fname
->disk_name
.len
= fname
->crypto_buf
.len
;
430 f2fs_fname_crypto_free_buffer(&fname
->crypto_buf
);
434 void f2fs_fname_free_filename(struct f2fs_filename
*fname
)
436 kfree(fname
->crypto_buf
.name
);
437 fname
->crypto_buf
.name
= NULL
;
438 fname
->usr_fname
= NULL
;
439 fname
->disk_name
.name
= NULL
;