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

Commit d475a507 authored by Richard Weinberger's avatar Richard Weinberger
Browse files

ubifs: Add skeleton for fscrypto



This is the first building block to provide file level
encryption on UBIFS.

Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 6a5e98ab
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -50,3 +50,14 @@ config UBIFS_ATIME_SUPPORT
	  strictatime is the "heavy", relatime is "lighter", etc.

	  If unsure, say 'N'

config UBIFS_FS_ENCRYPTION
	bool "UBIFS Encryption"
	depends on UBIFS_FS
	select FS_ENCRYPTION
	default n
	help
	  Enable encryption of UBIFS files and directories. This
	  feature is similar to ecryptfs, but it is more memory
	  efficient since it avoids caching the encrypted and
	  decrypted pages in the page cache.
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
ubifs-y += misc.o
ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o

fs/ubifs/crypto.c

0 → 100644
+46 −0
Original line number Diff line number Diff line
#include "ubifs.h"

static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len)
{
	return ubifs_xattr_get(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
			       ctx, len);
}

static int ubifs_crypt_set_context(struct inode *inode, const void *ctx,
				   size_t len, void *fs_data)
{
	return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
			       ctx, len, 0);
}

static bool ubifs_crypt_empty_dir(struct inode *inode)
{
	return ubifs_check_dir_empty(inode) == 0;
}

static unsigned int ubifs_crypt_max_namelen(struct inode *inode)
{
	if (S_ISLNK(inode->i_mode))
		return UBIFS_MAX_INO_DATA;
	else
		return UBIFS_MAX_NLEN;
}

static int ubifs_key_prefix(struct inode *inode, u8 **key)
{
	static char prefix[] = "ubifs:";

	*key = prefix;

	return sizeof(prefix) - 1;
}

struct fscrypt_operations ubifs_crypt_operations = {
	.flags			= FS_CFLG_INPLACE_ENCRYPTION,
	.get_context		= ubifs_crypt_get_context,
	.set_context		= ubifs_crypt_set_context,
	.is_encrypted		= ubifs_crypt_is_encrypted,
	.empty_dir		= ubifs_crypt_empty_dir,
	.max_namelen		= ubifs_crypt_max_namelen,
	.key_prefix		= ubifs_key_prefix,
};
+27 −1
Original line number Diff line number Diff line
@@ -85,11 +85,26 @@ static int inherit_flags(const struct inode *dir, umode_t mode)
 * initializes it. Returns new inode in case of success and an error code in
 * case of failure.
 */
struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
			      umode_t mode)
{
	int err;
	struct inode *inode;
	struct ubifs_inode *ui;
	bool encrypted = false;

	if (ubifs_crypt_is_encrypted(dir)) {
		err = fscrypt_get_encryption_info(dir);
		if (err) {
			ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err);
			return ERR_PTR(err);
		}

		if (!fscrypt_has_encryption_key(dir))
			return ERR_PTR(-EPERM);

		encrypted = true;
	}

	inode = new_inode(c->vfs_sb);
	ui = ubifs_inode(inode);
@@ -165,6 +180,17 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
	 */
	ui->creat_sqnum = ++c->max_sqnum;
	spin_unlock(&c->cnt_lock);

	if (encrypted) {
		err = fscrypt_inherit_context(dir, inode, &encrypted, true);
		if (err) {
			ubifs_err(c, "fscrypt_inherit_context failed: %i", err);
			make_bad_inode(inode);
			iput(inode);
			return ERR_PTR(err);
		}
	}

	return inode;
}

+35 −0
Original line number Diff line number Diff line
@@ -181,6 +181,41 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
		mnt_drop_write_file(file);
		return err;
	}
	case FS_IOC_SET_ENCRYPTION_POLICY: {
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
		struct fscrypt_policy policy;

		if (copy_from_user(&policy,
				   (struct fscrypt_policy __user *)arg,
				   sizeof(policy)))
			return -EFAULT;

		err = fscrypt_process_policy(file, &policy);

		return err;
#else
		return -EOPNOTSUPP;
#endif
	}
	case FS_IOC_GET_ENCRYPTION_POLICY: {
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
		struct fscrypt_policy policy;

		if (!ubifs_crypt_is_encrypted(inode))
			return -ENOENT;

		err = fscrypt_get_policy(inode, &policy);
		if (err)
			return err;

		if (copy_to_user((void __user *)arg, &policy, sizeof(policy)))
			return -EFAULT;

		return 0;
#else
		return -EOPNOTSUPP;
#endif
	}

	default:
		return -ENOTTY;
Loading