From: Theodore Ts'o <tytso@mit.edu>
To: Ext4 Developers List <linux-ext4@vger.kernel.org>
Cc: mhalcrow@google.com, Theodore Ts'o <tytso@mit.edu>
Subject: [PATCH-v2 20/20] ext4 crypto: enable encryption feature flag
Date: Sun, 12 Apr 2015 23:16:36 -0400 [thread overview]
Message-ID: <1428894996-7852-21-git-send-email-tytso@mit.edu> (raw)
In-Reply-To: <1428894996-7852-1-git-send-email-tytso@mit.edu>
Also add the test dummy encryption mode flag so we can more easily
test the encryption patches using xfstests.
Change-Id: I63a7f5b969738eed81b2f12715cfff161a988d84
Signed-off-by: Michael Halcrow <mhalcrow@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
fs/ext4/crypto_key.c | 27 +++++++++++++++------------
fs/ext4/crypto_policy.c | 18 +++++++++++++++---
fs/ext4/ext4.h | 17 +++++++++++++----
fs/ext4/ialloc.c | 3 ++-
fs/ext4/namei.c | 9 ++++++---
fs/ext4/super.c | 29 ++++++++++++++++++++++++++++-
6 files changed, 79 insertions(+), 24 deletions(-)
diff --git a/fs/ext4/crypto_key.c b/fs/ext4/crypto_key.c
index 572bd97..c8392af 100644
--- a/fs/ext4/crypto_key.c
+++ b/fs/ext4/crypto_key.c
@@ -98,6 +98,7 @@ int ext4_generate_encryption_key(struct inode *inode)
struct ext4_encryption_key *master_key;
struct ext4_encryption_context ctx;
struct user_key_payload *ukp;
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
int res = ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
&ctx, sizeof(ctx));
@@ -109,6 +110,20 @@ int ext4_generate_encryption_key(struct inode *inode)
}
res = 0;
+ if (S_ISREG(inode->i_mode))
+ crypt_key->mode = ctx.contents_encryption_mode;
+ else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+ crypt_key->mode = ctx.filenames_encryption_mode;
+ else {
+ printk(KERN_ERR "ext4 crypto: Unsupported inode type.\n");
+ BUG();
+ }
+ crypt_key->size = ext4_encryption_key_size(crypt_key->mode);
+ BUG_ON(!crypt_key->size);
+ if (DUMMY_ENCRYPTION_ENABLED(sbi)) {
+ memset(crypt_key->raw, 0x42, EXT4_AES_256_XTS_KEY_SIZE);
+ goto out;
+ }
memcpy(full_key_descriptor, EXT4_KEY_DESC_PREFIX,
EXT4_KEY_DESC_PREFIX_SIZE);
sprintf(full_key_descriptor + EXT4_KEY_DESC_PREFIX_SIZE,
@@ -129,21 +144,9 @@ int ext4_generate_encryption_key(struct inode *inode)
goto out;
}
master_key = (struct ext4_encryption_key *)ukp->data;
-
- if (S_ISREG(inode->i_mode))
- crypt_key->mode = ctx.contents_encryption_mode;
- else if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
- crypt_key->mode = ctx.filenames_encryption_mode;
- else {
- printk(KERN_ERR "ext4 crypto: Unsupported inode type.\n");
- BUG();
- }
- crypt_key->size = ext4_encryption_key_size(crypt_key->mode);
- BUG_ON(!crypt_key->size);
BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE !=
EXT4_KEY_DERIVATION_NONCE_SIZE);
BUG_ON(master_key->size != EXT4_AES_256_XTS_KEY_SIZE);
- BUG_ON(crypt_key->size < EXT4_AES_256_CBC_KEY_SIZE);
res = ext4_derive_key_aes(ctx.nonce, master_key->raw, crypt_key->raw);
out:
if (keyring_key)
diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c
index 5b4fbb3..89024ec 100644
--- a/fs/ext4/crypto_policy.c
+++ b/fs/ext4/crypto_policy.c
@@ -158,13 +158,25 @@ int ext4_inherit_context(struct inode *parent, struct inode *child)
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT,
&ctx, sizeof(ctx));
- if (res != sizeof(ctx))
- return -ENOENT;
-
+ if (res != sizeof(ctx)) {
+ if (DUMMY_ENCRYPTION_ENABLED(EXT4_SB(parent->i_sb))) {
+ ctx.format = EXT4_ENCRYPTION_CONTEXT_FORMAT_V1;
+ ctx.contents_encryption_mode =
+ EXT4_ENCRYPTION_MODE_AES_256_XTS;
+ ctx.filenames_encryption_mode =
+ EXT4_ENCRYPTION_MODE_AES_256_CTS;
+ memset(ctx.master_key_descriptor, 0x42,
+ EXT4_KEY_DESCRIPTOR_SIZE);
+ res = 0;
+ } else {
+ goto out;
+ }
+ }
get_random_bytes(ctx.nonce, EXT4_KEY_DERIVATION_NONCE_SIZE);
res = ext4_xattr_set(child, EXT4_XATTR_INDEX_ENCRYPTION,
EXT4_XATTR_NAME_ENCRYPTION_CONTEXT, &ctx,
sizeof(ctx), 0);
+out:
if (!res)
ext4_set_inode_flag(child, EXT4_INODE_ENCRYPT);
return res;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7ae0454..c4e2a2e 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1189,8 +1189,16 @@ struct ext4_super_block {
/*
* run-time mount flags
*/
-#define EXT4_MF_MNTDIR_SAMPLED 0x0001
-#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
+#define EXT4_MF_MNTDIR_SAMPLED 0x0001
+#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
+#define EXT4_MF_TEST_DUMMY_ENCRYPTION 0x0004
+
+#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->s_mount_flags & \
+ EXT4_MF_TEST_DUMMY_ENCRYPTION))
+#else
+#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
+#endif
/* Number of quota types we support */
#define EXT4_MAXQUOTAS 2
@@ -1601,8 +1609,9 @@ static inline int ext4_encrypted_inode(struct inode *inode)
EXT4_FEATURE_INCOMPAT_EXTENTS| \
EXT4_FEATURE_INCOMPAT_64BIT| \
EXT4_FEATURE_INCOMPAT_FLEX_BG| \
- EXT4_FEATURE_INCOMPAT_MMP | \
- EXT4_FEATURE_INCOMPAT_INLINE_DATA)
+ EXT4_FEATURE_INCOMPAT_MMP | \
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \
+ EXT4_FEATURE_INCOMPAT_ENCRYPT)
#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 8f37c9e..12571b4 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -999,7 +999,8 @@ got:
/* If the directory encrypted, then we should encrypt the inode. */
if ((S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode)) &&
- ext4_encrypted_inode(dir))
+ (ext4_encrypted_inode(dir) ||
+ DUMMY_ENCRYPTION_ENABLED(sbi)))
ext4_set_inode_flag(inode, EXT4_INODE_ENCRYPT);
ext4_set_inode_flags(inode);
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index b67c216..49159df 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2577,7 +2577,8 @@ retry:
if (!err && IS_DIRSYNC(dir))
ext4_handle_sync(handle);
#ifdef CONFIG_EXT4_FS_ENCRYPTION
- if (!err && ext4_encrypted_inode(dir)) {
+ if (!err && (ext4_encrypted_inode(dir) ||
+ DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb)))) {
err = ext4_inherit_context(dir, inode);
if (err)
ext4_unlink(dir, dentry);
@@ -2782,7 +2783,8 @@ out_clear_inode:
if (IS_DIRSYNC(dir))
ext4_handle_sync(handle);
#ifdef CONFIG_EXT4_FS_ENCRYPTION
- if (ext4_encrypted_inode(dir)) {
+ if (ext4_encrypted_inode(dir) ||
+ DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb))) {
err = ext4_inherit_context(dir, inode);
if (err)
ext4_unlink(dir, dentry);
@@ -3187,7 +3189,8 @@ static int ext4_symlink(struct inode *dir,
disk_link.len = len + 1;
disk_link.name = (char *) symname;
- encryption_required = ext4_encrypted_inode(dir);
+ encryption_required = (ext4_encrypted_inode(dir) ||
+ DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb)));
if (encryption_required)
disk_link.len = encrypted_symlink_data_len(len) + 1;
if (disk_link.len > dir->i_sb->s_blocksize)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 1a44e74..31a8574 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1136,7 +1136,7 @@ enum {
Opt_commit, Opt_min_batch_time, Opt_max_batch_time, Opt_journal_dev,
Opt_journal_path, Opt_journal_checksum, Opt_journal_async_commit,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
- Opt_data_err_abort, Opt_data_err_ignore,
+ Opt_data_err_abort, Opt_data_err_ignore, Opt_test_dummy_encryption,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
@@ -1223,6 +1223,7 @@ static const match_table_t tokens = {
{Opt_init_itable, "init_itable"},
{Opt_noinit_itable, "noinit_itable"},
{Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
+ {Opt_test_dummy_encryption, "test_dummy_encryption"},
{Opt_removed, "check=none"}, /* mount option from ext2/3 */
{Opt_removed, "nocheck"}, /* mount option from ext2/3 */
{Opt_removed, "reservation"}, /* mount option from ext2/3 */
@@ -1423,6 +1424,7 @@ static const struct mount_opts {
{Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
{Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
{Opt_max_dir_size_kb, 0, MOPT_GTE0},
+ {Opt_test_dummy_encryption, 0, MOPT_GTE0},
{Opt_err, 0, 0}
};
@@ -1593,6 +1595,15 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
}
*journal_ioprio =
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
+ } else if (token == Opt_test_dummy_encryption) {
+#ifdef CONFIG_EXT4_FS_ENCRYPTION
+ sbi->s_mount_flags |= EXT4_MF_TEST_DUMMY_ENCRYPTION;
+ ext4_msg(sb, KERN_WARNING,
+ "Test dummy encryption mode enabled");
+#else
+ ext4_msg(sb, KERN_WARNING,
+ "Test dummy encryption mount option ignored");
+#endif
} else if (m->flags & MOPT_DATAJ) {
if (is_remount) {
if (!sbi->s_journal)
@@ -2685,11 +2696,13 @@ static struct attribute *ext4_attrs[] = {
EXT4_INFO_ATTR(lazy_itable_init);
EXT4_INFO_ATTR(batched_discard);
EXT4_INFO_ATTR(meta_bg_resize);
+EXT4_INFO_ATTR(encryption);
static struct attribute *ext4_feat_attrs[] = {
ATTR_LIST(lazy_itable_init),
ATTR_LIST(batched_discard),
ATTR_LIST(meta_bg_resize),
+ ATTR_LIST(encryption),
NULL,
};
@@ -3673,6 +3686,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
goto failed_mount;
}
+ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT) &&
+ es->s_encryption_level) {
+ ext4_msg(sb, KERN_ERR, "Unsupported encryption level %d",
+ es->s_encryption_level);
+ goto failed_mount;
+ }
+
if (sb->s_blocksize != blocksize) {
/* Validate the filesystem blocksize */
if (!sb_set_blocksize(sb, blocksize)) {
@@ -4036,6 +4056,13 @@ no_journal:
}
}
+ if (unlikely(sbi->s_mount_flags & EXT4_MF_TEST_DUMMY_ENCRYPTION) &&
+ !(sb->s_flags & MS_RDONLY) &&
+ !EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT)) {
+ EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_ENCRYPT);
+ ext4_commit_super(sb, 1);
+ }
+
/*
* Get the # of file system overhead blocks from the
* superblock if present.
--
2.3.0
prev parent reply other threads:[~2015-04-13 3:18 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-13 3:16 [PATCH-v2 00/20] ext4 encryption patches Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 01/20] ext4 crypto: add ext4_mpage_readpages() Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 02/20] ext4 crypto: reserve codepoints used by the ext4 encryption feature Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 03/20] ext4 crypto: add ext4 encryption Kconfig Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 04/20] ext4 crypto: export ext4_empty_dir() Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 05/20] ext4 crypto: add encryption xattr support Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 06/20] ext4 crypto: add encryption policy and password salt support Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 07/20] ext4 crypto: add ext4 encryption facilities Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 08/20] ext4 crypto: add encryption key management facilities Theodore Ts'o
2015-05-27 13:39 ` Dmitry Monakhov
2015-05-27 17:06 ` Theodore Ts'o
2015-05-27 18:37 ` Theodore Ts'o
2015-05-29 17:55 ` Dmitry Monakhov
2015-05-29 18:12 ` Dmitry Monakhov
2015-05-29 20:03 ` Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 09/20] ext4 crypto: validate context consistency on lookup Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 10/20] ext4 crypto: inherit encryption policies on inode and directory create Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 11/20] ext4 crypto: implement the ext4 encryption write path Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 12/20] ext4 crypto: implement the ext4 decryption read path Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 13/20] ext4 crypto: filename encryption facilities Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 14/20] ext4 crypto: teach ext4_htree_store_dirent() to store decrypted filenames Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 15/20] ext4 crypto: insert encrypted filenames into a leaf directory block Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 16/20] ext4 crypto: partial update to namei.c for fname crypto Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 17/20] ext4 crypto: filename encryption modifications Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 18/20] ext4 crypto: enable filename encryption Theodore Ts'o
2015-04-13 3:16 ` [PATCH-v2 19/20] ext4 crypto: Add symlink encryption Theodore Ts'o
2015-04-13 3:16 ` Theodore Ts'o [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1428894996-7852-21-git-send-email-tytso@mit.edu \
--to=tytso@mit.edu \
--cc=linux-ext4@vger.kernel.org \
--cc=mhalcrow@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).