@@ -23,6 +23,7 @@
#include <linux/pagemap.h>
#include <linux/mempool.h>
#include <linux/module.h>
+#include <linux/random.h>
#include <linux/scatterlist.h>
#include <linux/ratelimit.h>
#include <crypto/skcipher.h>
@@ -69,6 +70,31 @@ void fscrypt_free_bounce_page(struct page *bounce_page)
}
EXPORT_SYMBOL(fscrypt_free_bounce_page);
+int fscrypt_mode_ivsize(struct inode *inode)
+{
+ struct fscrypt_info *ci;
+
+ if (!fscrypt_needs_contents_encryption(inode))
+ return 0;
+
+ ci = inode->i_crypt_info;
+ if (WARN_ON_ONCE(!ci))
+ return 0;
+ return ci->ci_mode->ivsize;
+}
+EXPORT_SYMBOL(fscrypt_mode_ivsize);
+
+/**
+ * fscrypt_generate_random_iv() - initialize a new iv for an IV_FROM_FS filesystem
+ * @inode: the inode to which the new IV will belong
+ * @iv: an output buffer, long enough for the requisite IV
+ */
+void fscrypt_generate_random_iv(struct inode *inode, u8 *iv)
+{
+ get_random_bytes(iv, fscrypt_mode_ivsize(inode));
+}
+EXPORT_SYMBOL(fscrypt_generate_random_iv);
+
/*
* Generate the IV for the given logical block number within the given file.
* For filenames encryption, lblk_num == 0.
@@ -317,6 +317,9 @@ static inline struct page *fscrypt_pagecache_page(struct page *bounce_page)
void fscrypt_free_bounce_page(struct page *bounce_page);
+int fscrypt_mode_ivsize(struct inode *inode);
+void fscrypt_generate_random_iv(struct inode *inode, u8 *iv);
+
/* policy.c */
int fscrypt_have_same_policy(struct inode *inode1, struct inode *inode2);
int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg);
Unlike other filesystems, which store all necessary encryption context in the per-inode fscrypt context, btrfs will need to store an IV per extent in order to support snapshots and reflinks. To avoid exposing the internal details of extents to fscrypt, and to centralize IV generation in fscrypt, this change provides fscrypt_generate_random_iv(), which will be called for each newly created btrfs extent and will populate a btrfs-provided buffer with a new IV. Additionally, a function to get the necessary buffer size, fscrypt_mode_ivsize(), is also necessary. Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> --- fs/crypto/crypto.c | 26 ++++++++++++++++++++++++++ include/linux/fscrypt.h | 3 +++ 2 files changed, 29 insertions(+)