diff mbox series

[04/21] fscrypt: add a function for a filesystem to generate an IV

Message ID 40f17d7f64a80e0d2746972b4f6b4b5831d4f455.1660744500.git.sweettea-kernel@dorminy.me (mailing list archive)
State Superseded
Headers show
Series btrfs: add fscrypt integration | expand

Commit Message

Sweet Tea Dorminy Aug. 17, 2022, 2:49 p.m. UTC
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(+)
diff mbox series

Patch

diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index e78be66bbf01..e0e30d64837e 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -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.
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 1686b25f6d9c..ff572f8a88f8 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -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);