History

fscrypt: add inline encryption support

Add support for inline encryption to fs/crypto/. With "inline encryption", the block layer handles the decryption/encryption as part of the bio, instead of the filesystem doing the crypto itself via Linux's crypto API. This model is needed in order to take advantage of the inline encryption hardware present on most modern mobile SoCs. To use inline encryption, the filesystem needs to be mounted with '-o inlinecrypt'. Blk-crypto will then be used instead of the traditional filesystem-layer crypto whenever possible to encrypt the contents of any encrypted files in that filesystem. Fscrypt still provides the key and IV to use, and the actual ciphertext on-disk is still the same; therefore it's testable using the existing fscrypt ciphertext verification tests. Note that since blk-crypto has a fallback to Linux's crypto API, and also supports all the encryption modes currently supported by fscrypt, this feature is usable and testable even without actual inline encryption hardware. Per-filesystem changes will be needed to set encryption contexts when submitting bios and to implement the 'inlinecrypt' mount option. This patch just adds the common code.

Satya Tangirala committed 6 years ago

Commit 5fee3601 parent 457e7a112 files · +673 −47Browse files

Showing the changes to include/linux (1 of 12 files). Show all

Unified · Split

include/linux/fscrypt.h+82−0
@@ -69,6 +69,9 @@ struct fscrypt_operations { · 68 unmodified lines
6969 bool (*has_stable_inodes)(struct super_block *sb);
7070 void (*get_ino_and_lblk_bits)(struct super_block *sb,
7171 int *ino_bits_ret, int *lblk_bits_ret);
72+ int (*get_num_devices)(struct super_block *sb);
73+ void (*get_devices)(struct super_block *sb,
74+ struct request_queue **devs);
7275 };
7376
7477 static inline bool fscrypt_has_encryption_key(const struct inode *inode)
@@ -537,6 +540,85 @@ static inline void fscrypt_set_ops(struct super_block *sb, · 462 unmodified lines
537540
538541 #endif /* !CONFIG_FS_ENCRYPTION */
539542
543+/* inline_crypt.c */
544+#ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT
545+
546+bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode);
547+
548+void fscrypt_set_bio_crypt_ctx(struct bio *bio,
549+ const struct inode *inode, u64 first_lblk,
550+ gfp_t gfp_mask);
551+
552+void fscrypt_set_bio_crypt_ctx_bh(struct bio *bio,
553+ const struct buffer_head *first_bh,
554+ gfp_t gfp_mask);
555+
556+bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode,
557+ u64 next_lblk);
558+
559+bool fscrypt_mergeable_bio_bh(struct bio *bio,
560+ const struct buffer_head *next_bh);
561+
562+#else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
563+
564+static inline bool __fscrypt_inode_uses_inline_crypto(const struct inode *inode)
565+{
566+ return false;
567+}
568+
569+static inline void fscrypt_set_bio_crypt_ctx(struct bio *bio,
570+ const struct inode *inode,
571+ u64 first_lblk, gfp_t gfp_mask) { }
572+
573+static inline void fscrypt_set_bio_crypt_ctx_bh(
574+ struct bio *bio,
575+ const struct buffer_head *first_bh,
576+ gfp_t gfp_mask) { }
577+
578+static inline bool fscrypt_mergeable_bio(struct bio *bio,
579+ const struct inode *inode,
580+ u64 next_lblk)
581+{
582+ return true;
583+}
584+
585+static inline bool fscrypt_mergeable_bio_bh(struct bio *bio,
586+ const struct buffer_head *next_bh)
587+{
588+ return true;
589+}
590+#endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */
591+
592+/**
593+ * fscrypt_inode_uses_inline_crypto() - test whether an inode uses inline
594+ * encryption
595+ * @inode: an inode. If encrypted, its key must be set up.
596+ *
597+ * Return: true if the inode requires file contents encryption and if the
598+ * encryption should be done in the block layer via blk-crypto rather
599+ * than in the filesystem layer.
600+ */
601+static inline bool fscrypt_inode_uses_inline_crypto(const struct inode *inode)
602+{
603+ return fscrypt_needs_contents_encryption(inode) &&
604+ __fscrypt_inode_uses_inline_crypto(inode);
605+}
606+
607+/**
608+ * fscrypt_inode_uses_fs_layer_crypto() - test whether an inode uses fs-layer
609+ * encryption
610+ * @inode: an inode. If encrypted, its key must be set up.
611+ *
612+ * Return: true if the inode requires file contents encryption and if the
613+ * encryption should be done in the filesystem layer rather than in the
614+ * block layer via blk-crypto.
615+ */
616+static inline bool fscrypt_inode_uses_fs_layer_crypto(const struct inode *inode)
617+{
618+ return fscrypt_needs_contents_encryption(inode) &&
619+ !__fscrypt_inode_uses_inline_crypto(inode);
620+}
621+
540622 /**
541623 * fscrypt_require_key() - require an inode's encryption key
542624 * @inode: the inode we need the key for