/*
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * Per-File-Key (PFK).
 *
 * This driver is responsible for overall management of various
 * Per File Encryption variants that work on top of or as part of different
 * file systems.
 *
 * The driver has the following purpose :
 * 1) Define priorities between PFE's if more than one is enabled
 * 2) Extract key information from inode
 * 3) Load and manage various keys in ICE HW engine
 * 4) It should be invoked from various layers in FS/BLOCK/STORAGE DRIVER
 *    that need to take decision on HW encryption management of the data
 *    Some examples:
 *	BLOCK LAYER: when it takes decision on whether 2 chunks can be united
 *	to one encryption / decryption request sent to the HW
 *
 *	UFS DRIVER: when it need to configure ICE HW with a particular key slot
 *	to be used for encryption / decryption
 *
 * PFE variants can differ on particular way of storing the cryptographic info
 * inside inode, actions to be taken upon file operations, etc., but the common
 * properties are described above
 *
 */


/* Uncomment the line below to enable debug messages */
/* #define DEBUG 1 */
#define pr_fmt(fmt)	"pfk [%s]: " fmt, __func__

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/printk.h>
#include <linux/bio.h>
#include <linux/security.h>
#include <crypto/algapi.h>
#include <crypto/ice.h>

#include <linux/pfk.h>

#include "pfk_kc.h"
#include "objsec.h"
#include "pfk_ice.h"
#include "pfk_ext4.h"
#include "pfk_f2fs.h"
#include "pfk_internal.h"
//#include "ext4.h"

static bool pfk_ready;


/* might be replaced by a table when more than one cipher is supported */
#define PFK_SUPPORTED_KEY_SIZE 32
#define PFK_SUPPORTED_SALT_SIZE 32

/* Various PFE types and function tables to support each one of them */
enum pfe_type {EXT4_CRYPT_PFE, F2FS_CRYPT_PFE, INVALID_PFE};

typedef int (*pfk_parse_inode_type)(const struct bio *bio,
	const struct inode *inode,
	struct pfk_key_info *key_info,
	enum ice_cryto_algo_mode *algo,
	bool *is_pfe,
	const char *storage_type);

typedef bool (*pfk_allow_merge_bio_type)(const struct bio *bio1,
	const struct bio *bio2, const struct inode *inode1,
	const struct inode *inode2);

static const pfk_parse_inode_type pfk_parse_inode_ftable[] = {
	/* EXT4_CRYPT_PFE */ &pfk_ext4_parse_inode,
    /* F2FS_CRYPT_PFE */ &pfk_f2fs_parse_inode,
};

static const pfk_allow_merge_bio_type pfk_allow_merge_bio_ftable[] = {
	/* EXT4_CRYPT_PFE */ &pfk_ext4_allow_merge_bio,
    /* F2FS_CRYPT_PFE */ &pfk_f2fs_allow_merge_bio,
};

static void __exit pfk_exit(void)
{
	pfk_ready = false;
	pfk_ext4_deinit();
	pfk_f2fs_deinit();
	pfk_kc_deinit();
}

static int __init pfk_init(void)
{

	int ret = 0;

	ret = pfk_ext4_init();
	if (ret != 0)
		goto fail;

	ret = pfk_f2fs_init();
	if (ret != 0)
		goto fail;

	ret = pfk_kc_init();
	if (ret != 0) {
		pr_err("could init pfk key cache, error %d\n", ret);
		pfk_ext4_deinit();
		pfk_f2fs_deinit();
		goto fail;
	}

	pfk_ready = true;
	pr_info("Driver initialized successfully\n");

	return 0;

fail:
	pr_err("Failed to init driver\n");
	return -ENODEV;
}

/*
 * If more than one type is supported simultaneously, this function will also
 * set the priority between them
 */
static enum pfe_type pfk_get_pfe_type(const struct inode *inode)
{
	if (!inode)
		return INVALID_PFE;

	if (pfk_is_ext4_type(inode))
		return EXT4_CRYPT_PFE;

	if (pfk_is_f2fs_type(inode))
		return F2FS_CRYPT_PFE;

	return INVALID_PFE;
}

/**
 * inode_to_filename() - get the filename from inode pointer.
 * @inode: inode pointer
 *
 * it is used for debug prints.
 *
 * Return: filename string or "unknown".
 */
char *inode_to_filename(const struct inode *inode)
{
	struct dentry *dentry = NULL;
	char *filename = NULL;

	if (!inode)
		return "NULL";

	if (hlist_empty(&inode->i_dentry))
		return "unknown";

	dentry = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias);
	filename = dentry->d_iname;

	return filename;
}

/**
 * pfk_is_ready() - driver is initialized and ready.
 *
 * Return: true if the driver is ready.
 */
static inline bool pfk_is_ready(void)
{
	return pfk_ready;
}

/**
 * pfk_bio_get_inode() - get the inode from a bio.
 * @bio: Pointer to BIO structure.
 *
 * Walk the bio struct links to get the inode.
 * Please note, that in general bio may consist of several pages from
 * several files, but in our case we always assume that all pages come
 * from the same file, since our logic ensures it. That is why we only
 * walk through the first page to look for inode.
 *
 * Return: pointer to the inode struct if successful, or NULL otherwise.
 *
 */
static struct inode *pfk_bio_get_inode(const struct bio *bio)
{
	if (!bio)
		return NULL;
	if (!bio_has_data((struct bio *)bio))
		return NULL;
	if (!bio->bi_io_vec)
		return NULL;
	if (!bio->bi_io_vec->bv_page)
		return NULL;

	if (PageAnon(bio->bi_io_vec->bv_page)) {
		struct inode *inode;

		/* Using direct-io (O_DIRECT) without page cache */
		inode = dio_bio_get_inode((struct bio *)bio);
		pr_debug("inode on direct-io, inode = 0x%pK.\n", inode);

		return inode;
	}

	if (!page_mapping(bio->bi_io_vec->bv_page))
		return NULL;

	return page_mapping(bio->bi_io_vec->bv_page)->host;
}

/**
 * pfk_key_size_to_key_type() - translate key size to key size enum
 * @key_size: key size in bytes
 * @key_size_type: pointer to store the output enum (can be null)
 *
 * return 0 in case of success, error otherwise (i.e not supported key size)
 */
int pfk_key_size_to_key_type(size_t key_size,
	enum ice_crpto_key_size *key_size_type)
{
	/*
	 *  currently only 32 bit key size is supported
	 *  in the future, table with supported key sizes might
	 *  be introduced
	 */

	if (key_size != PFK_SUPPORTED_KEY_SIZE) {
		pr_err("not supported key size %zu\n", key_size);
		return -EINVAL;
	}

	if (key_size_type)
		*key_size_type = ICE_CRYPTO_KEY_SIZE_256;

	return 0;
}

/*
 * Retrieves filesystem type from inode's superblock
 */
bool pfe_is_inode_filesystem_type(const struct inode *inode,
	const char *fs_type)
{
	if (!inode || !fs_type)
		return false;

	if (!inode->i_sb)
		return false;

	if (!inode->i_sb->s_type)
		return false;

	return (strcmp(inode->i_sb->s_type->name, fs_type) == 0);
}

/**
 * pfk_get_key_for_bio() - get the encryption key to be used for a bio
 *
 * @bio: pointer to the BIO
 * @key_info: pointer to the key information which will be filled in
 * @algo_mode: optional pointer to the algorithm identifier which will be set
 * @is_pfe: will be set to false if the BIO should be left unencrypted
 *
 * Return: 0 if a key is being used, otherwise a -errno value
 */
static int pfk_get_key_for_bio(const struct bio *bio,
		struct pfk_key_info *key_info,
		enum ice_cryto_algo_mode *algo_mode,
		bool *is_pfe, unsigned int *data_unit)
{
	const struct inode *inode;
	enum pfe_type which_pfe;
	const struct blk_encryption_key *key;
	char *s_type = NULL;

	inode = pfk_bio_get_inode(bio);
	which_pfe = pfk_get_pfe_type(inode);
	s_type = (char *)pfk_kc_get_storage_type();

	if (data_unit && (bio_dun(bio) ||
			!memcmp(s_type, "ufs", strlen("ufs"))))
		*data_unit = 1 << ICE_CRYPTO_DATA_UNIT_4_KB;

	if (which_pfe != INVALID_PFE) {
		/* Encrypted file; override ->bi_crypt_key */
		pr_debug("parsing inode %lu with PFE type %d\n",
			 inode->i_ino, which_pfe);
		return (*(pfk_parse_inode_ftable[which_pfe]))
				(bio, inode, key_info, algo_mode, is_pfe,
					(const char *)s_type);
	}

	/*
	 * bio is not for an encrypted file.  Use ->bi_crypt_key if it was set.
	 * Otherwise, don't encrypt/decrypt the bio.
	 */
	key = bio->bi_crypt_key;
	if (!key) {
		*is_pfe = false;
		return -EINVAL;
	}

	/* Note: the "salt" is really just the second half of the XTS key. */
	BUILD_BUG_ON(sizeof(key->raw) !=
		     PFK_SUPPORTED_KEY_SIZE + PFK_SUPPORTED_SALT_SIZE);
	key_info->key = &key->raw[0];
	key_info->key_size = PFK_SUPPORTED_KEY_SIZE;
	key_info->salt = &key->raw[PFK_SUPPORTED_KEY_SIZE];
	key_info->salt_size = PFK_SUPPORTED_SALT_SIZE;
	if (algo_mode)
		*algo_mode = ICE_CRYPTO_ALGO_MODE_AES_XTS;
	return 0;
}


/**
 * pfk_load_key_start() - loads PFE encryption key to the ICE
 *			  Can also be invoked from non
 *			  PFE context, in this case it
 *			  is not relevant and is_pfe
 *			  flag is set to false
 *
 * @bio: Pointer to the BIO structure
 * @ice_setting: Pointer to ice setting structure that will be filled with
 * ice configuration values, including the index to which the key was loaded
 *  @is_pfe: will be false if inode is not relevant to PFE, in such a case
 * it should be treated as non PFE by the block layer
 *
 * Returns the index where the key is stored in encryption hw and additional
 * information that will be used later for configuration of the encryption hw.
 *
 * Must be followed by pfk_load_key_end when key is no longer used by ice
 *
 */
int pfk_load_key_start(const struct bio *bio,
		struct ice_crypto_setting *ice_setting, bool *is_pfe,
		bool async, int ice_rev)
{
	int ret = 0;
	struct pfk_key_info key_info = {NULL, NULL, 0, 0};
	enum ice_cryto_algo_mode algo_mode = ICE_CRYPTO_ALGO_MODE_AES_XTS;
	enum ice_crpto_key_size key_size_type = 0;
	unsigned int data_unit = 1 << ICE_CRYPTO_DATA_UNIT_512_B;
	u32 key_index = 0;

	if (!is_pfe) {
		pr_err("is_pfe is NULL\n");
		return -EINVAL;
	}

	/*
	 * only a few errors below can indicate that
	 * this function was not invoked within PFE context,
	 * otherwise we will consider it PFE
	 */
	*is_pfe = true;

	if (!pfk_is_ready())
		return -ENODEV;

	if (!ice_setting) {
		pr_err("ice setting is NULL\n");
		return -EINVAL;
	}

	ret = pfk_get_key_for_bio(bio, &key_info, &algo_mode, is_pfe,
					&data_unit);

	if (ret != 0)
		return ret;

	ret = pfk_key_size_to_key_type(key_info.key_size, &key_size_type);
	if (ret != 0)
		return ret;

	ret = pfk_kc_load_key_start(key_info.key, key_info.key_size,
			key_info.salt, key_info.salt_size, &key_index, async,
			data_unit, ice_rev);
	if (ret) {
		if (ret != -EBUSY && ret != -EAGAIN)
			pr_err("start: could not load key into pfk key cache, error %d\n",
					ret);

		return ret;
	}

	ice_setting->key_size = key_size_type;
	ice_setting->algo_mode = algo_mode;
	/* hardcoded for now */
	ice_setting->key_mode = ICE_CRYPTO_USE_LUT_SW_KEY;
	ice_setting->key_index = key_index;

	pr_debug("loaded key for file %s key_index %d\n",
		inode_to_filename(pfk_bio_get_inode(bio)), key_index);

	return 0;
}

/**
 * pfk_load_key_end() - marks the PFE key as no longer used by ICE
 *			Can also be invoked from non
 *			PFE context, in this case it is not
 *			relevant and is_pfe flag is
 *			set to false
 *
 * @bio: Pointer to the BIO structure
 * @is_pfe: Pointer to is_pfe flag, which will be true if function was invoked
 *			from PFE context
 */
int pfk_load_key_end(const struct bio *bio, bool *is_pfe)
{
	int ret = 0;
	struct pfk_key_info key_info = {NULL, NULL, 0, 0};

	if (!is_pfe) {
		pr_err("is_pfe is NULL\n");
		return -EINVAL;
	}

	/* only a few errors below can indicate that
	 * this function was not invoked within PFE context,
	 * otherwise we will consider it PFE
	 */
	*is_pfe = true;

	if (!pfk_is_ready())
		return -ENODEV;

	ret = pfk_get_key_for_bio(bio, &key_info, NULL, is_pfe, NULL);
	if (ret != 0)
		return ret;

	pfk_kc_load_key_end(key_info.key, key_info.key_size,
		key_info.salt, key_info.salt_size);

	pr_debug("finished using key for file %s\n",
		inode_to_filename(pfk_bio_get_inode(bio)));

	return 0;
}

/**
 * pfk_allow_merge_bio() - Check if 2 BIOs can be merged.
 * @bio1:	Pointer to first BIO structure.
 * @bio2:	Pointer to second BIO structure.
 *
 * Prevent merging of BIOs from encrypted and non-encrypted
 * files, or files encrypted with different key.
 * Also prevent non encrypted and encrypted data from the same file
 * to be merged (ecryptfs header if stored inside file should be non
 * encrypted)
 * This API is called by the file system block layer.
 *
 * Return: true if the BIOs allowed to be merged, false
 * otherwise.
 */
bool pfk_allow_merge_bio(const struct bio *bio1, const struct bio *bio2)
{
	const struct blk_encryption_key *key1;
	const struct blk_encryption_key *key2;
	const struct inode *inode1;
	const struct inode *inode2;
	enum pfe_type which_pfe1;
	enum pfe_type which_pfe2;

	if (!pfk_is_ready())
		return false;

	if (!bio1 || !bio2)
		return false;

	if (bio1 == bio2)
		return true;

	key1 = bio1->bi_crypt_key;
	key2 = bio2->bi_crypt_key;

	inode1 = pfk_bio_get_inode(bio1);
	inode2 = pfk_bio_get_inode(bio2);

	which_pfe1 = pfk_get_pfe_type(inode1);
	which_pfe2 = pfk_get_pfe_type(inode2);

	/*
	 * If one bio is for an encrypted file and the other is for a different
	 * type of encrypted file or for blocks that are not part of an
	 * encrypted file, do not merge.
	 */
	if (which_pfe1 != which_pfe2)
		return false;

	if (which_pfe1 != INVALID_PFE) {
		/* Both bios are for the same type of encrypted file. */
	return (*(pfk_allow_merge_bio_ftable[which_pfe1]))(bio1, bio2,
		inode1, inode2);
	}

	/*
	 * Neither bio is for an encrypted file.  Merge only if the default keys
	 * are the same (or both are NULL).
	 */
	return key1 == key2 ||
		(key1 && key2 &&
		 !crypto_memneq(key1->raw, key2->raw, sizeof(key1->raw)));
}

/**
 * Flush key table on storage core reset. During core reset key configuration
 * is lost in ICE. We need to flash the cache, so that the keys will be
 * reconfigured again for every subsequent transaction
 */
void pfk_clear_on_reset(void)
{
	if (!pfk_is_ready())
		return;

	pfk_kc_clear_on_reset();
}

module_init(pfk_init);
module_exit(pfk_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Per-File-Key driver");
