Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ddb2447 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

ext4 crypto: enable encryption feature flag



Also add the test dummy encryption mode flag so we can more easily
test the encryption patches using xfstests.

Signed-off-by: default avatarMichael Halcrow <mhalcrow@google.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent f348c252
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -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)
+15 −3
Original line number Diff line number Diff line
@@ -169,13 +169,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;
+13 −4
Original line number Diff line number Diff line
@@ -1202,6 +1202,14 @@ struct ext4_super_block {
 */
#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
@@ -1614,7 +1622,8 @@ static inline int ext4_encrypted_inode(struct inode *inode)
					 EXT4_FEATURE_INCOMPAT_64BIT| \
					 EXT4_FEATURE_INCOMPAT_FLEX_BG| \
					 EXT4_FEATURE_INCOMPAT_MMP | \
					 EXT4_FEATURE_INCOMPAT_INLINE_DATA)
					 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| \
+2 −1
Original line number Diff line number Diff line
@@ -998,7 +998,8 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,

	/* 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);
+6 −3
Original line number Diff line number Diff line
@@ -2582,7 +2582,8 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, umode_t mode,
		ext4_set_aops(inode);
		err = 0;
#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) {
				clear_nlink(inode);
@@ -2777,7 +2778,8 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
	if (err)
		goto out_clear_inode;
#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)
			goto out_clear_inode;
@@ -3202,7 +3204,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)
Loading