fscrypt: export fscrypt_fname_encrypt and fscrypt_fname_encrypted_size
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> Reviewed-by: Xiubo Li <xiubli@redhat.com> Acked-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
18cc912b8a
commit
d3e94fdc4e
|
@ -86,7 +86,8 @@ static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
|
|||
/**
|
||||
* fscrypt_fname_encrypt() - encrypt a filename
|
||||
* @inode: inode of the parent directory (for regular filenames)
|
||||
* or of the symlink (for symlink targets)
|
||||
* or of the symlink (for symlink targets). Key must already be
|
||||
* set up.
|
||||
* @iname: the filename to encrypt
|
||||
* @out: (output) the encrypted filename
|
||||
* @olen: size of the encrypted filename. It must be at least @iname->len.
|
||||
|
@ -137,6 +138,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fscrypt_fname_encrypt);
|
||||
|
||||
/**
|
||||
* fname_decrypt() - decrypt a filename
|
||||
|
@ -264,9 +266,9 @@ static int fscrypt_base64url_decode(const char *src, int srclen, u8 *dst)
|
|||
return bp - dst;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -280,6 +282,29 @@ 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. Key must
|
||||
* already be set up.
|
||||
* @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 that are shorter than the maximum length may have their lengths
|
||||
* increased slightly by encryption, due to padding that is applied.
|
||||
*
|
||||
* Return: false if the orig_len is greater 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_GPL(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
|
||||
|
@ -435,8 +460,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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -327,6 +327,10 @@ 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);
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue