/*
 * 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/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>

#include <linux/slab.h>

#include <linux/spinlock.h>
#include <linux/list.h>

#include <sdp/dek_common.h>

typedef struct __kek_pack {
    int engine_id;
    int user_id;

	struct list_head list;

	struct list_head kek_list_head;
	spinlock_t kek_list_lock;
}kek_pack_t;

typedef struct __kek_item {
	struct list_head list;

	int kek_type;
	kek_t kek;
}kek_item_t;

#define KEK_PACK_DEBUG		0

#if KEK_PACK_DEBUG
#define KEK_PACK_LOGD(FMT, ...) printk("KEK_PACK[%d] %s :: " FMT , current->pid, __func__, ##__VA_ARGS__)
#else
#define KEK_PACK_LOGD(FMT, ...)
#endif /* PUB_CRYPTO_DEBUG */
#define KEK_PACK_LOGE(FMT, ...) printk("KEK_PACK[%d] %s :: " FMT , current->pid, __func__, ##__VA_ARGS__)

struct list_head kek_pack_list_head;
spinlock_t kek_pack_list_lock;
spinlock_t del_kek_pack_lock;

void init_kek_pack(void) {
	spin_lock_init(&kek_pack_list_lock);
	spin_lock_init(&del_kek_pack_lock);
	INIT_LIST_HEAD(&kek_pack_list_head);
}

static kek_pack_t *find_kek_pack(int engine_id) {
	struct list_head *entry;

	spin_lock(&kek_pack_list_lock);

	list_for_each(entry, &kek_pack_list_head) {
		kek_pack_t *pack = list_entry(entry, kek_pack_t, list);

		if(pack->engine_id == engine_id) {
			KEK_PACK_LOGD("Found kek-pack : %d\n", engine_id);
			spin_unlock(&kek_pack_list_lock);
			return pack;
		}
	}
	spin_unlock(&kek_pack_list_lock);

	KEK_PACK_LOGE("Can't find kek-pack : %d\n", engine_id);

	return NULL;
}

static int __add_kek(kek_pack_t *pack, kek_t *kek, kek_item_t *item) {

	if(kek == NULL) return -EINVAL;
	if(pack == NULL) return -EINVAL;

	INIT_LIST_HEAD(&item->list);
	item->kek_type = kek->type;
	memcpy(&item->kek, kek, sizeof(kek_t));

	list_add_tail(&item->list, &pack->kek_list_head);

    KEK_PACK_LOGD("item %p\n", item);

	return 0;
}

static kek_item_t *find_kek_item(kek_pack_t *pack, int kek_type) {
	struct list_head *entry;

	if(pack == NULL) return NULL;

	list_for_each(entry, &pack->kek_list_head) {
		kek_item_t *item = list_entry(entry, kek_item_t, list);

		if(item->kek_type == kek_type) {
			KEK_PACK_LOGD("Found kek-item : %d\n", kek_type);

			return item;
		}
	}

	KEK_PACK_LOGD("Can't find kek %d : %d\n", kek_type, pack->engine_id);

	return NULL;
}

static void del_kek_item(kek_item_t *item) {
    KEK_PACK_LOGD("entered\n");

    if(item) {
        list_del(&item->list);
        kzfree(item);
    } else {
        KEK_PACK_LOGD("given item is NULL\n");
    }
}

int add_kek_pack(int engine_id, int user_id) {
	kek_pack_t *new_kek_pack;

	KEK_PACK_LOGD("entered\n");

	if(find_kek_pack(engine_id)) {
		KEK_PACK_LOGE("kek-pack for %d already exists\n", engine_id);
		return -EEXIST;
	}

	new_kek_pack = kmalloc(sizeof(kek_pack_t), GFP_KERNEL);
	if(new_kek_pack == NULL) {
		KEK_PACK_LOGE("can't alloc memory for kek_pack_t\n");
		return -EINVAL;
	}

    new_kek_pack->engine_id = engine_id;
    new_kek_pack->user_id = user_id;
	spin_lock_init(&new_kek_pack->kek_list_lock);
	INIT_LIST_HEAD(&new_kek_pack->kek_list_head);

	spin_lock(&kek_pack_list_lock);
	list_add_tail(&new_kek_pack->list, &kek_pack_list_head);
	spin_unlock(&kek_pack_list_lock);

	return 0;
}

void del_kek_pack(int engine_id) {
	struct list_head *entry, *q;
	kek_pack_t *pack;

	spin_lock(&del_kek_pack_lock);
	KEK_PACK_LOGD("entered\n");
	pack = find_kek_pack(engine_id);
	if(pack == NULL) {
	    spin_unlock(&del_kek_pack_lock);
	    return;
	}

	spin_lock(&pack->kek_list_lock);
	list_for_each_safe(entry, q, &pack->kek_list_head) {
		kek_item_t *item = list_entry(entry, kek_item_t, list);
		KEK_PACK_LOGD("entry %p item %p\n", entry, item);
		del_kek_item(item);
	}
	spin_unlock(&pack->kek_list_lock);

	list_del(&pack->list);
	kzfree(pack);
	spin_unlock(&del_kek_pack_lock);
}

int add_kek(int engine_id, kek_t *kek) {
	int rc;
	kek_pack_t *pack;
	kek_item_t *item;

	KEK_PACK_LOGD("entered\n");
	pack = find_kek_pack(engine_id);
	if(pack == NULL) return -ENOENT;

	item = kmalloc(sizeof(kek_item_t), GFP_KERNEL);
	if(item == NULL) {
		rc = -ENOMEM;
	} else {
		spin_lock(&pack->kek_list_lock);
		if(find_kek_item(pack, kek->type)) {
			spin_unlock(&pack->kek_list_lock);
			kzfree(item);		
			return -EEXIST;
		}
		rc = __add_kek(pack, kek, item);

		spin_unlock(&pack->kek_list_lock);
	}

	if(rc) KEK_PACK_LOGE("%s failed. rc = %d", __func__, rc);

	return rc;
}

int del_kek(int engine_id, int kek_type) {
	kek_pack_t *pack;
	kek_item_t *item;

	KEK_PACK_LOGD("entered\n");

	pack = find_kek_pack(engine_id);
	if(pack == NULL) return -ENOENT;

	spin_lock(&pack->kek_list_lock);
	item = find_kek_item(pack, kek_type);
	if(item == NULL) {
		spin_unlock(&pack->kek_list_lock);
		return -ENOENT;
	}

	del_kek_item(item);
	spin_unlock(&pack->kek_list_lock);

	return 0;
}

/*
 * I wanted to have some ref-count for kek_item_t that doesn't disturb
 * ongoing dek process. But the returned kek won't be zero-freed if the process
 * never returns.
 *
 * So allocate new memory and let the user call put accordingly
 */
kek_t *get_kek(int engine_id, int kek_type, int *rc) {
	kek_pack_t *pack;
	kek_item_t *item;
	kek_t *kek;
	int userid = from_kuid(&init_user_ns, current_uid()) / PER_USER_RANGE;

	KEK_PACK_LOGD("entered [%d]\n", from_kuid(&init_user_ns, current_uid()));

	pack = find_kek_pack(engine_id);
	if(pack == NULL) {
	    *rc = -ENOENT;
	    return NULL;
	}

	// Across user engine access denied for Knox containers.
	if(!is_root() &&
			(pack->user_id >= 100 && pack->user_id < 200) &&
	        (pack->user_id != userid)) {
	    KEK_PACK_LOGE("Permission denied to get kek\n");
	    KEK_PACK_LOGE("pack->user_id[%d] != userid[%d]\n",
	            pack->user_id, userid);

		*rc = -EACCES;
		return NULL;
	}
	kek = kmalloc(sizeof(kek_t), GFP_KERNEL);
	if (kek == NULL) {
		*rc = -ENOMEM;
		return NULL;
	}

	spin_lock(&pack->kek_list_lock);
	item = find_kek_item(pack, kek_type);
	if (item) {
		*rc = 0;
		memcpy(kek, &item->kek, sizeof(kek_t));
		spin_unlock(&pack->kek_list_lock);
		return kek;
	} else {
		spin_unlock(&pack->kek_list_lock);
		kzfree(kek);
	}

    *rc = -ENOENT;
	return NULL;
}

void put_kek(kek_t *kek) {
	KEK_PACK_LOGD("entered\n");

	if(kek) kzfree(kek);
}

int is_kek_pack(int engine_id) {
	kek_pack_t *pack;

	KEK_PACK_LOGD("entered\n");

	pack = find_kek_pack(engine_id);
	if(pack) return 1;

	return 0;
}

int is_kek(int engine_id, int kek_type) {
	kek_pack_t *pack;
	kek_item_t *item;

	KEK_PACK_LOGD("entered\n");

	pack = find_kek_pack(engine_id);
	if(pack == NULL) return 0;
	spin_lock(&pack->kek_list_lock);
	item = find_kek_item(pack, kek_type);
	spin_unlock(&pack->kek_list_lock);
	if(item) {
		return 1;
	}

	return 0;
}
