]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
fscrypt: export fscrypt_fname_encrypt and fscrypt_fname_encrypted_size
authorJeff Layton <jlayton@kernel.org>
Fri, 8 Jan 2021 20:34:38 +0000 (15:34 -0500)
committerJeff Layton <jlayton@kernel.org>
Tue, 7 Dec 2021 15:32:46 +0000 (10:32 -0500)
For ceph, we want to use our own scheme for handling filenames that are
are longer than NAME_MAX after encryption and base64 encoding. This
allows us to have a consistent view of the encrypted filenames for
clients that don't support fscrypt and clients that do but that don't
have the key.

Currently, fs/crypto only supports encrypting filenames using
fscrypt_setup_filename, but that also handles encoding nokey names. Ceph
can't use that because it handles nokey names in a different way.

Export fscrypt_fname_encrypt. Rename fscrypt_fname_encrypted_size to
__fscrypt_fname_encrypted_size and add a new wrapper called
fscrypt_fname_encrypted_size that takes an inode argument rather than a
pointer to a fscrypt_policy union.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
fs/crypto/fname.c
fs/crypto/fscrypt_private.h
fs/crypto/hooks.c
include/linux/fscrypt.h

index 8fa23d525b5c016b01e15d4a71fce9418f278247..3be04b5aa5702eed779aa77f8d78510b1fbf3852 100644 (file)
@@ -130,6 +130,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
 
        return 0;
 }
+EXPORT_SYMBOL(fscrypt_fname_encrypt);
 
 /**
  * fname_decrypt() - decrypt a filename
@@ -257,9 +258,9 @@ int fscrypt_base64url_decode(const char *src, int srclen, u8 *dst)
 }
 EXPORT_SYMBOL(fscrypt_base64url_decode);
 
-bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
-                                 u32 orig_len, u32 max_len,
-                                 u32 *encrypted_len_ret)
+bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
+                                   u32 orig_len, u32 max_len,
+                                   u32 *encrypted_len_ret)
 {
        int padding = 4 << (fscrypt_policy_flags(policy) &
                            FSCRYPT_POLICY_FLAGS_PAD_MASK);
@@ -273,6 +274,28 @@ bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
        return true;
 }
 
+/**
+ * fscrypt_fname_encrypted_size() - calculate length of encrypted filename
+ * @inode:             parent inode of dentry name being encrypted
+ * @orig_len:          length of the original filename
+ * @max_len:           maximum length to return
+ * @encrypted_len_ret: where calculated length should be returned (on success)
+ *
+ * Filenames must be padded out to at least the end of an fscrypt block before
+ * encrypting them. This calculates the length of an encrypted filename.
+ *
+ * Return: false if the orig_len is shorter than max_len. Otherwise, true and
+ *        fill out encrypted_len_ret with the length (up to max_len).
+ */
+bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
+                                 u32 max_len, u32 *encrypted_len_ret)
+{
+       return __fscrypt_fname_encrypted_size(&inode->i_crypt_info->ci_policy,
+                                             orig_len, max_len,
+                                             encrypted_len_ret);
+}
+EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
+
 /**
  * fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames
  * @max_encrypted_len: maximum length of encrypted filenames the buffer will be
@@ -428,8 +451,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
                return ret;
 
        if (fscrypt_has_encryption_key(dir)) {
-               if (!fscrypt_fname_encrypted_size(&dir->i_crypt_info->ci_policy,
-                                                 iname->len, NAME_MAX,
+               if (!fscrypt_fname_encrypted_size(dir, iname->len, NAME_MAX,
                                                  &fname->crypto_buf.len))
                        return -ENAMETOOLONG;
                fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
index 5b0a9e6478b5d4acb8cec249c92217831bdbbac1..51e42767dbd6d5a1d6d6066aeeebbffd38afd500 100644 (file)
@@ -297,14 +297,11 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
                         const struct fscrypt_info *ci);
 
 /* fname.c */
-int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
-                         u8 *out, unsigned int olen);
-bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
-                                 u32 orig_len, u32 max_len,
-                                 u32 *encrypted_len_ret);
+bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
+                                   u32 orig_len, u32 max_len,
+                                    u32 *encrypted_len_ret);
 
 /* hkdf.c */
-
 struct fscrypt_hkdf {
        struct crypto_shash *hmac_tfm;
 };
index af74599ae1cf0677111a228d4438174c2c595569..7c01025879b38fb9bc22b56163f28375d2119d99 100644 (file)
@@ -228,9 +228,9 @@ int fscrypt_prepare_symlink(struct inode *dir, const char *target,
         * counting it (even though it is meaningless for ciphertext) is simpler
         * for now since filesystems will assume it is there and subtract it.
         */
-       if (!fscrypt_fname_encrypted_size(policy, len,
-                                         max_len - sizeof(struct fscrypt_symlink_data),
-                                         &disk_link->len))
+       if (!__fscrypt_fname_encrypted_size(policy, len,
+                                           max_len - sizeof(struct fscrypt_symlink_data),
+                                           &disk_link->len))
                return -ENAMETOOLONG;
        disk_link->len += sizeof(struct fscrypt_symlink_data);
 
index 671181d196a873bd2f0430dcecd7feee0f18c5f2..c90e176b58439439acb6013ea5ede7a13a6a4c8a 100644 (file)
@@ -308,8 +308,12 @@ void fscrypt_free_inode(struct inode *inode);
 int fscrypt_drop_inode(struct inode *inode);
 
 /* fname.c */
+int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
+                         u8 *out, unsigned int olen);
 int fscrypt_base64url_encode(const u8 *src, int len, char *dst);
 int fscrypt_base64url_decode(const char *src, int len, u8 *dst);
+bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
+                                 u32 max_len, u32 *encrypted_len_ret);
 int fscrypt_setup_filename(struct inode *inode, const struct qstr *iname,
                           int lookup, struct fscrypt_name *fname);