/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *
 * Sensitive Data Protection
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/pagemap.h>
#include <linux/crypto.h>
#include <asm/unaligned.h>

#include <sdp/fs_handler.h>
#include "ecryptfs_dek.h"
#include "ecryptfs_sdp_chamber.h"
#include "mm.h"

extern int dek_encrypt_dek_efs(int engine_id, dek_t *plainDek, dek_t *encDek);
extern int dek_decrypt_dek_efs(int engine_id, dek_t *encDek, dek_t *plainDek);
extern int dek_is_locked(int engine_id);

static int ecryptfs_update_crypt_flag(struct dentry *dentry, enum sdp_op operation);

static const char* get_op_name(enum sdp_op operation) {
   switch (operation)
   {
      case TO_SENSITIVE: return "TO_SENSITIVE";
      case TO_PROTECTED: return "TO_PROTECTED";
      default: return "OP_UNKNOWN";
   }
}

static int ecryptfs_set_key(struct ecryptfs_crypt_stat *crypt_stat) {
	int rc = 0;

	mutex_lock(&crypt_stat->cs_tfm_mutex);
	if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {
		rc = crypto_ablkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
				crypt_stat->key_size);
		if (rc) {
			ecryptfs_printk(KERN_ERR,
					"Error setting key; rc = [%d]\n",
					rc);
			rc = -EINVAL;
			goto out;
		}
		crypt_stat->flags |= ECRYPTFS_KEY_SET;
		crypt_stat->flags |= ECRYPTFS_KEY_VALID;
	}
out:
	mutex_unlock(&crypt_stat->cs_tfm_mutex);
	return rc;
}

int ecryptfs_is_sdp_locked(int engine_id)
{
    if(engine_id < 0) {
        DEK_LOGE("invalid engine_id[%d]\n", engine_id);
        return 0;
    }

	return dek_is_locked(engine_id);
}

extern int32_t sdp_mm_set_process_sensitive(unsigned int proc_id);

#define PSEUDO_KEY_LEN 32
const char pseudo_key[PSEUDO_KEY_LEN] = {
        // PSEUDOSDP
        0x50, 0x53, 0x55, 0x45, 0x44, 0x4f, 0x53, 0x44,
        0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void ecryptfs_clean_sdp_dek(struct ecryptfs_crypt_stat *crypt_stat)
{
    int rc = 0;

	printk("%s()\n", __func__);

	if(crypt_stat->tfm) {
	    mutex_lock(&crypt_stat->cs_tfm_mutex);
	    rc = crypto_ablkcipher_setkey(crypt_stat->tfm, pseudo_key,
	            PSEUDO_KEY_LEN);
        if (rc) {
            ecryptfs_printk(KERN_ERR,
                    "Error cleaning tfm rc = [%d]\n",
                    rc);
        }
	    mutex_unlock(&crypt_stat->cs_tfm_mutex);
	}

	memset(crypt_stat->key, 0, ECRYPTFS_MAX_KEY_BYTES);
	crypt_stat->flags &= ~(ECRYPTFS_KEY_SET);
	crypt_stat->flags &= ~(ECRYPTFS_KEY_VALID);
}

int ecryptfs_get_sdp_dek(struct ecryptfs_crypt_stat *crypt_stat)
{
	int rc = 0;

	if((crypt_stat->flags & ECRYPTFS_KEY_SET) && (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
		DEK_LOGE("get_sdp_dek: key is already set (success)\n");
		return 0;
	}

	if(crypt_stat->flags & ECRYPTFS_DEK_SDP_ENABLED) {
		if(crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
			dek_t DEK;

			if(crypt_stat->engine_id < 0) {
		        DEK_LOGE("get_sdp_dek: invalid engine-id"
		                "(ECRYPTFS_DEK_IS_SENSITIVE:ON, engine_id:%d)\n", crypt_stat->engine_id);
		        goto out;
			}
			memset(crypt_stat->key, 0, ECRYPTFS_MAX_KEY_BYTES);

			if (crypt_stat->sdp_dek.type != DEK_TYPE_PLAIN) {
				rc = dek_decrypt_dek_efs(crypt_stat->engine_id, &crypt_stat->sdp_dek, &DEK);
			} else {
				DEK_LOGE("DEK already plaintext, skip decryption");
				rc = 0;
				goto out;
			}
			if (rc < 0) {
				DEK_LOGE("Error decypting dek; rc = [%d]\n", rc);
				memset(&DEK, 0, sizeof(dek_t));
				goto out;
			}
			memcpy(crypt_stat->key, DEK.buf, DEK.len);
			crypt_stat->key_size = DEK.len;
			memset(&DEK, 0, sizeof(dek_t));
		} else {
#if ECRYPTFS_DEK_DEBUG
			DEK_LOGD("file is not sensitive\n");
#endif
		}
	}
out:
/*
 * Succeeded
 */
	if(!rc) {
		sdp_mm_set_process_sensitive(current->pid);
		rc = ecryptfs_set_key(crypt_stat);
	} else {
	/*
	 * Error
	 */
		ecryptfs_clean_sdp_dek(crypt_stat);
	}

	return rc;
}

int write_dek_packet(char *dest,
		struct ecryptfs_crypt_stat *crypt_stat,
		size_t *written) {
	*written = 0;
	dest[(*written)++] = ECRYPTFS_DEK_PACKET_TYPE;

	memset(dest + *written, 0, PKG_NAME_SIZE);
	memcpy(dest + *written, current->comm, PKG_NAME_SIZE);
	(*written) += PKG_NAME_SIZE;

	put_unaligned_be32(from_kuid(&init_user_ns, current_euid()), dest + *written);
	(*written) += 4;

	memset(dest + *written, 0, DEK_MAXLEN);

	if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
        if(crypt_stat->flags & ECRYPTFS_DEK_MULTI_ENGINE) {
            put_unaligned_be32(crypt_stat->engine_id, dest + *written);
            (*written) += 4;
        }

		put_unaligned_be32(crypt_stat->sdp_dek.type, dest + *written);
		(*written) += 4;
		put_unaligned_be32(crypt_stat->sdp_dek.len, dest + *written);
		(*written) += 4;
		memcpy(dest + *written, crypt_stat->sdp_dek.buf, crypt_stat->sdp_dek.len);
		(*written) += crypt_stat->sdp_dek.len;
	}

	return 0;
}

int parse_dek_packet(char *data,
		struct ecryptfs_crypt_stat *crypt_stat,
		size_t *packet_size) {
	int rc = 0;
	char temp_comm[PKG_NAME_SIZE]; //test
	int temp_euid;
	int sdp_dek_type;
	int sdp_dek_len;

	if (crypt_stat->file_version == 0)
		return -EPERM;

	(*packet_size) = 0;

	if (data[(*packet_size)++] != ECRYPTFS_DEK_PACKET_TYPE) {
		DEK_LOGE("First byte != 0x%.2x; invalid packet\n",
				ECRYPTFS_DEK_PACKET_TYPE);
		rc = -EINVAL;
	}

	memcpy(temp_comm, &data[*packet_size], PKG_NAME_SIZE);
	(*packet_size) += PKG_NAME_SIZE;

	temp_euid = get_unaligned_be32(data + *packet_size);
	(*packet_size) += 4;

	if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
	    if(crypt_stat->flags & ECRYPTFS_DEK_MULTI_ENGINE) {
	        crypt_stat->engine_id = get_unaligned_be32(data + *packet_size);
	        (*packet_size) += 4;
	    } else {
	        /**
	         * If eCryptfs header doesn't have engine-id,
	         * we assign it from mount_crypt_stat->userid
	         * (Fils created in old version)
	         */
	        crypt_stat->engine_id = crypt_stat->mount_crypt_stat->userid;
	    }

		sdp_dek_type = get_unaligned_be32(data + *packet_size);
		if(sdp_dek_type < 0 || sdp_dek_type > 6)
			return -EINVAL;
		crypt_stat->sdp_dek.type = sdp_dek_type;
		(*packet_size) += 4;
		
		sdp_dek_len = get_unaligned_be32(data + *packet_size);
		if(sdp_dek_len <= 0 || sdp_dek_len > DEK_MAXLEN)
			return -EFAULT;
		crypt_stat->sdp_dek.len = sdp_dek_len;
		(*packet_size) += 4;
		
		
		memcpy(crypt_stat->sdp_dek.buf, &data[*packet_size], crypt_stat->sdp_dek.len);
		(*packet_size) += crypt_stat->sdp_dek.len;
	}
	
#if ECRYPTFS_DEK_DEBUG
	DEK_LOGD("%s() : comm : %s [euid:%d]\n",
		__func__, temp_comm, temp_euid);
#endif
	return rc;
}

static int ecryptfs_dek_copy_mount_wide_sigs_to_inode_sigs(
    struct ecryptfs_crypt_stat *crypt_stat,
    struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
    struct ecryptfs_global_auth_tok *global_auth_tok;
    int rc = 0;

    mutex_lock(&crypt_stat->keysig_list_mutex);
    mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);

    list_for_each_entry(global_auth_tok,
                &mount_crypt_stat->global_auth_tok_list,
                mount_crypt_stat_list) {
        if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK)
            continue;
        rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig);
        if (rc) {
            printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc);
            goto out;
        }
    }

out:
    mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
    mutex_unlock(&crypt_stat->keysig_list_mutex);
    return rc;
}

#if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS)
static void ecryptfs_propagate_flag(struct file *file, int userid, enum sdp_op operation) {
    struct file *f = file;
    do {
		if(!f)
			return ;

		DEK_LOGD("%s file: %p [%s]\n",__func__, f, f->f_inode->i_sb->s_type->name);
        if (operation == TO_SENSITIVE) {
			mapping_set_sensitive(f->f_mapping);
		} else {
			mapping_clear_sensitive(f->f_mapping);
		}
		f->f_mapping->userid = userid;
    } while (f->f_op->get_lower_file && (f = f->f_op->get_lower_file(f)));
}
#endif

void ecryptfs_set_mapping_sensitive(struct inode *ecryptfs_inode, int userid, enum sdp_op operation) {
#if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS)
	struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
	struct ecryptfs_inode_info *inode_info;
	
	inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
	DEK_LOGD("%s inode: %p lower_file_count: %d\n",__func__, ecryptfs_inode,atomic_read(&inode_info->lower_file_count));
	mount_crypt_stat = &ecryptfs_superblock_to_private(ecryptfs_inode->i_sb)->mount_crypt_stat;
	
	if (operation == TO_SENSITIVE) {
		mapping_set_sensitive(ecryptfs_inode->i_mapping);
	} else {
		mapping_clear_sensitive(ecryptfs_inode->i_mapping);
	}
	ecryptfs_inode->i_mapping->userid = userid;
	/*
	 * If FMP is in use, need to set flag to lower filesystems too recursively
	 */
	if (mount_crypt_stat->flags & ECRYPTFS_USE_FMP) {
		if(inode_info->lower_file) {
			ecryptfs_propagate_flag(inode_info->lower_file, userid, operation);
		}
	}
#else
	if (operation == TO_SENSITIVE) {
		mapping_set_sensitive(ecryptfs_inode->i_mapping);
	} else {
		mapping_clear_sensitive(ecryptfs_inode->i_mapping);
	}
	ecryptfs_inode->i_mapping->userid = userid;
#endif
}

/*
 * set sensitive flag, update metadata
 * Set cached inode pages to sensitive
 */
static int ecryptfs_update_crypt_flag(struct dentry *dentry, enum sdp_op operation)
{
	int rc = 0;
	struct inode *inode;
	struct inode *lower_inode;
	struct ecryptfs_crypt_stat *crypt_stat;
	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
	u32 tmp_flags;

	DEK_LOGE("%s(operation:%s) entered\n", __func__, get_op_name(operation));

	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
	mount_crypt_stat = &ecryptfs_superblock_to_private(dentry->d_sb)->mount_crypt_stat;
	if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
		ecryptfs_init_crypt_stat(crypt_stat);
	inode = dentry->d_inode;
	lower_inode = ecryptfs_inode_to_lower(inode);

	/*
	* To update metadata we need to make sure keysig_list contains fekek.
	* Because our EDEK is stored along with key for protected file.
	*/
	if(list_empty(&crypt_stat->keysig_list))
        	ecryptfs_dek_copy_mount_wide_sigs_to_inode_sigs(crypt_stat, mount_crypt_stat);

	mutex_lock(&crypt_stat->cs_mutex);
	rc = ecryptfs_get_lower_file(dentry, inode);
	if (rc) {
		mutex_unlock(&crypt_stat->cs_mutex);
		DEK_LOGE("ecryptfs_get_lower_file rc=%d\n", rc);
		return rc;
	}

	tmp_flags = crypt_stat->flags;
	if (operation == TO_SENSITIVE) {
		crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;
		crypt_stat->flags |= ECRYPTFS_DEK_MULTI_ENGINE;
		/*
		* Set sensitive to inode mapping
		*/
		ecryptfs_set_mapping_sensitive(inode, mount_crypt_stat->userid, TO_SENSITIVE);
	} else {
		crypt_stat->flags &= ~ECRYPTFS_DEK_IS_SENSITIVE;
        crypt_stat->flags &= ~ECRYPTFS_DEK_MULTI_ENGINE;

		/*
		* Set protected to inode mapping
		*/
		ecryptfs_set_mapping_sensitive(inode, mount_crypt_stat->userid, TO_PROTECTED);
	}

	rc = ecryptfs_write_metadata(dentry, inode);
	if (rc) {
		crypt_stat->flags = tmp_flags;
		DEK_LOGE("ecryptfs_write_metadata rc=%d\n", rc);
		goto out;
	}

	rc = ecryptfs_write_inode_size_to_metadata(inode);
	if (rc) {
		DEK_LOGE("Problem with "
				"ecryptfs_write_inode_size_to_metadata; "
				"rc = [%d]\n", rc);
		goto out;
	}

out:
	mutex_unlock(&crypt_stat->cs_mutex);
	ecryptfs_put_lower_file(inode);
	fsstack_copy_attr_all(inode, lower_inode);
	return rc;
}

void ecryptfs_fs_request_callback(int opcode, int ret, unsigned long ino) {
    DEK_LOGD("%s opcode<%d> ret<%d> ino<%ld>\n", __func__, opcode, ret, ino);
}

int ecryptfs_sdp_set_sensitive(int engine_id, struct dentry *dentry) {
	int rc = 0;
	struct inode *inode = dentry->d_inode;
	struct ecryptfs_crypt_stat *crypt_stat =
			&ecryptfs_inode_to_private(inode)->crypt_stat;
	dek_t DEK;
    int id_bak = crypt_stat->engine_id;

	DEK_LOGD("%s(%s)\n", __func__, dentry->d_name.name);

	if(S_ISDIR(inode->i_mode)) {
        crypt_stat->engine_id = engine_id;
        crypt_stat->flags |= ECRYPTFS_DEK_IS_SENSITIVE;

        rc = 0;
	} else if(S_ISREG(inode->i_mode)) {
	    crypt_stat->engine_id = engine_id;

    	if (crypt_stat->key_size > ECRYPTFS_MAX_KEY_BYTES ||
	    		crypt_stat->key_size > DEK_MAXLEN ||
	    		crypt_stat->key_size > UINT_MAX){
	    	DEK_LOGE("%s Too large key_size\n", __func__);
	    	rc = -EFAULT;
    		goto out;
	    }
	    memcpy(DEK.buf, crypt_stat->key, crypt_stat->key_size);
	    DEK.len = (unsigned int)crypt_stat->key_size;
	    DEK.type = DEK_TYPE_PLAIN;

	    rc = dek_encrypt_dek_efs(crypt_stat->engine_id, &DEK,  &crypt_stat->sdp_dek);
	    if (rc < 0) {
	        DEK_LOGE("Error encrypting dek; rc = [%d]\n", rc);
	        memset(&crypt_stat->sdp_dek, 0, sizeof(dek_t));
	        goto out;
	    }
#if 0
	    /*
	     * We don't have to clear FEK after set-sensitive.
	     * FEK will be closed when the file is closed
	     */
	    memset(crypt_stat->key, 0, crypt_stat->key_size);
	    crypt_stat->flags &= ~(ECRYPTFS_KEY_SET);
#else
	    /*
	     * set-key after set sensitive file.
	     * Well when the file is just created and we do set_sensitive, the key is not set in the
	     * tfm. later SDP code, set-key is done while encryption, trying to decrypt EFEK.
	     *
	     * Here is the case in locked state user process want to create/write a file.
	     * the process open the file, automatically becomes sensitive by vault logic,
	     * and do the encryption, then boom. failed to decrypt EFEK even if FEK is
	     * available
	     */
	    rc = ecryptfs_set_key(crypt_stat);
	    if(rc) goto out;
#endif

	    ecryptfs_update_crypt_flag(dentry, TO_SENSITIVE);
	}

out:
    if(rc) crypt_stat->engine_id = id_bak;
	memset(&DEK, 0, sizeof(dek_t));
	return rc;
}

int ecryptfs_sdp_set_protected(struct dentry *dentry) {
    int rc = 0;
    struct inode *inode = dentry->d_inode;
    struct ecryptfs_crypt_stat *crypt_stat =
            &ecryptfs_inode_to_private(inode)->crypt_stat;

    DEK_LOGD("%s(%s)\n", __func__, dentry->d_name.name);

    if(IS_CHAMBER_DENTRY(dentry)) {
        DEK_LOGE("can't set-protected to chamber directory");
        return -EIO;
    }

    if(crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
        if(crypt_stat->engine_id < 0) {
            DEK_LOGE("%s: invalid engine-id (ECRYPTFS_DEK_IS_SENSITIVE:ON, engine_id:%d)\n",
                    __func__, crypt_stat->engine_id);
            return -EIO;
        }

        if(ecryptfs_is_sdp_locked(crypt_stat->engine_id)) {
            DEK_LOGE("%s: Failed. (engine_id:%d locked)\n",
                    __func__, crypt_stat->engine_id);
            return -EIO;
        }

        if(S_ISDIR(inode->i_mode)) {
            crypt_stat->flags &= ~ECRYPTFS_DEK_IS_SENSITIVE;
            rc = 0;
        } else {
            rc = ecryptfs_get_sdp_dek(crypt_stat);
            if (rc) {
                ecryptfs_printk(KERN_ERR, "%s Get SDP key failed\n", __func__);
                goto out;
            }
            /*
             * TODO : double check if need to compute iv here
             */
            rc = ecryptfs_compute_root_iv(crypt_stat);
            if (rc) {
                ecryptfs_printk(KERN_ERR, "Error computing "
                        "the root IV\n");
                goto out;
            }

            rc = ecryptfs_set_key(crypt_stat);
            if(rc) goto out;

        ecryptfs_update_crypt_flag(dentry, TO_PROTECTED);
        }
    } else {
        rc = 0; //already protected
    }
out:
    return rc;
}

int ecryptfs_sdp_convert_dek(struct dentry *dentry) {
	int rc = 0;
	struct inode *inode = dentry->d_inode;
	struct ecryptfs_crypt_stat *crypt_stat =
			&ecryptfs_inode_to_private(inode)->crypt_stat;
	dek_t DEK;

	rc = dek_decrypt_dek_efs(crypt_stat->engine_id, &crypt_stat->sdp_dek, &DEK);
	if (rc < 0) {
		DEK_LOGE("Error converting dek [DEC]; rc = [%d]\n", rc);
		goto out;
	}

	rc = dek_encrypt_dek_efs(crypt_stat->engine_id, &DEK,  &crypt_stat->sdp_dek);
	if (rc < 0) {
		DEK_LOGE("Error converting dek [ENC]; rc = [%d]\n", rc);
		goto out;
	}

	rc = ecryptfs_update_crypt_flag(dentry, TO_SENSITIVE);
	if (rc < 0) {
		DEK_LOGE("Error converting dek [FLAG]; rc = [%d]\n", rc);
		goto out;
	}
out:
	memset(&DEK, 0, sizeof(dek_t));
	return rc;
}

long ecryptfs_do_sdp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
	void __user *ubuf = (void __user *)arg;
	struct dentry *ecryptfs_dentry = file->f_path.dentry;
	struct inode *inode = ecryptfs_dentry->d_inode;
	struct ecryptfs_crypt_stat *crypt_stat =
			&ecryptfs_inode_to_private(inode)->crypt_stat;
//	struct dentry *fp_dentry =
//			ecryptfs_inode_to_private(inode)->lower_file->f_path.dentry;
    struct ecryptfs_mount_crypt_stat *mount_crypt_stat  =
            &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
    int rc;

	DEK_LOGD("%s(%s)\n", __func__, ecryptfs_dentry->d_name.name);

	if (!(crypt_stat->flags & ECRYPTFS_DEK_SDP_ENABLED)) {
		DEK_LOGE("SDP not enabled, skip sdp ioctl\n");
		return -ENOTTY;
	}

	switch (cmd) {
	case ECRYPTFS_IOCTL_GET_SDP_INFO: {
		dek_arg_get_sdp_info req;

		DEK_LOGD("ECRYPTFS_IOCTL_GET_SDP_INFO\n");
	
		memset(&req, 0, sizeof(dek_arg_get_sdp_info));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user\n");
			return -EFAULT;
		} else {
			mutex_lock(&crypt_stat->cs_mutex);

			req.engine_id = crypt_stat->engine_id;

			if (crypt_stat->flags & ECRYPTFS_DEK_SDP_ENABLED) {
				req.sdp_enabled = 1;
			} else {
				req.sdp_enabled = 0;
			}
			if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
				req.is_sensitive = 1;
			} else {
				req.is_sensitive = 0;
			}
            if (crypt_stat->flags & ECRYPTFS_SDP_IS_CHAMBER_DIR) {
                req.is_chamber = 1;
            } else {
                req.is_chamber = 0;
            }
			req.type = crypt_stat->sdp_dek.type;
			mutex_unlock(&crypt_stat->cs_mutex);
		}
		if(copy_to_user(ubuf, &req, sizeof(req))) {
			DEK_LOGE("can't copy to user\n");
			return -EFAULT;
		}

		break;
		}

    case ECRYPTFS_IOCTL_SET_PROTECTED: {
        ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_IOCTL_SET_PROTECTED\n");

        if(!is_current_epmd()) {
            DEK_LOGE("only epmd can call this\n");
            DEK_LOGE("Permission denied\n");
            return -EACCES;
        }

        if (!(crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE)) {
            DEK_LOGE("already protected file\n");
            return 0;
        }

        if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
            DEK_LOGE("Set protected directory\n");
            crypt_stat->flags &= ~ECRYPTFS_DEK_IS_SENSITIVE;
            break;
        }

        rc = ecryptfs_sdp_set_protected(ecryptfs_dentry);
        if (rc) {
            DEK_LOGE("Failed to set protected rc(%d)\n", rc);
            return rc;
        }
        break;
    }

	case ECRYPTFS_IOCTL_SET_SENSITIVE: {
		dek_arg_set_sensitive req;

		ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_IOCTL_SET_SENSITIVE\n");
		if (crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
			DEK_LOGE("already sensitive file\n");
			return 0;
		}

		memset(&req, 0, sizeof(dek_arg_set_sensitive));
		if(copy_from_user(&req, ubuf, sizeof(req))) {
			DEK_LOGE("can't copy from user\n");
			memset(&req, 0, sizeof(dek_arg_set_sensitive));
			return -EFAULT;
		} else {
		    rc = ecryptfs_sdp_set_sensitive(req.engine_id, ecryptfs_dentry);
			if (rc) {
				DEK_LOGE("failed to set sensitive rc(%d)\n", rc);
				memset(&req, 0, sizeof(dek_arg_set_sensitive));
				return rc;
			}
		}
		memset(&req, 0, sizeof(dek_arg_set_sensitive));
		break;
	}

	case ECRYPTFS_IOCTL_ADD_CHAMBER: {
	    dek_arg_add_chamber req;
	    int engineid;

        if (!S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
            DEK_LOGE("Not a directory\n");
            return -ENOTDIR;
        }

	    if(!is_current_epmd()) {
            DEK_LOGE("only epmd can call this\n");
            DEK_LOGE("Permission denied\n");
	        return -EACCES;
	    }

        memset(&req, 0, sizeof(req));
        if(copy_from_user(&req, ubuf, sizeof(req))) {
            DEK_LOGE("can't copy from user\n");
            memset(&req, 0, sizeof(req));
            return -EFAULT;
        }

	    if(!IS_UNDER_ROOT(ecryptfs_dentry)) {
            DEK_LOGE("Chamber has to be under root directory");
            return -EFAULT;
	    }

	    if(is_chamber_directory(mount_crypt_stat, ecryptfs_dentry->d_name.name, &engineid)) {
	        DEK_LOGE("Already chamber directory [%s] engine:%d\n",
	                ecryptfs_dentry->d_name.name, engineid);
	        if(engineid != req.engine_id) {
	            DEK_LOGE("Attemping to change engine-id[%d] -> [%d] : Failed\n",
	                    engineid, req.engine_id);
	            return -EACCES;
	        }

            set_chamber_flag(engineid, inode);
            break;
	    }

	    rc = add_chamber_directory(mount_crypt_stat, req.engine_id,
	            ecryptfs_dentry->d_name.name);
	    if(rc) {
	        DEK_LOGE("add_chamber_directory failed. %d\n", rc);
	        return rc;
	    }

        set_chamber_flag(req.engine_id, inode);
	    break;
	}

	case ECRYPTFS_IOCTL_REMOVE_CHAMBER: {
        if (!S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
            DEK_LOGE("Not a directory\n");
            return -ENOTDIR;
        }

        if(!is_current_epmd()) {
            //DEK_LOGE("only epmd can call this");
            DEK_LOGE("Permission denied");
            return -EACCES;
        }

        if(!IS_UNDER_ROOT(ecryptfs_dentry)) {
            DEK_LOGE("Chamber has to be under root directory");
            return -EFAULT;
        }

        if(!is_chamber_directory(mount_crypt_stat, ecryptfs_dentry->d_name.name, NULL)) {
            DEK_LOGE("Not a chamber directory [%s]\n", ecryptfs_dentry->d_name.name);

            clr_chamber_flag(inode);
            return 0;
        }

        del_chamber_directory(mount_crypt_stat, ecryptfs_dentry->d_name.name);
        clr_chamber_flag(inode);
	    break;
	}

	default: {
		return -EOPNOTSUPP;
		break;
		}

	}
	return 0;
}
