/*
* Copyright (C) 2017 Amlogic, Inc. 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 as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* *
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.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* *
Description:
*/

#include "key_manage_i.h"
#include <fdt.h>
#include <libfdt.h>

#define UNIFYKEY_DATAFORMAT_HEXDATA	    "hexdata"
#define UNIFYKEY_DATAFORMAT_HEXASCII	"hexascii"
#define UNIFYKEY_DATAFORMAT_ALLASCII	"allascii"

#define UNIFYKEY_DEVICE_EFUSEKEY	"efuse"
#define UNIFYKEY_DEVICE_NORMAL		"normal"
#define UNIFYKEY_DEVICE_SECURESKEY	"secure"

#define UNIFYKEY_PERMIT_READ		"read"
#define UNIFYKEY_PERMIT_WRITE		"write"
#define UNIFYKEY_PERMIT_DEL			"del"

static struct key_info_t unify_key_info={.key_num =0, .key_flag = 0, .efuse_version = -1, .encrypt_type = 0};
static struct key_item_t *unifykey_item=NULL;

static int unifykey_item_verify_check(struct key_item_t *key_item)
{
	if (!key_item) {
		KM_ERR("unify key item is invalid\n");
		return -1;
	}

	if ((key_item->dev == KEY_M_UNKNOW_DEV) ||(key_item->datFmt == KEY_M_MAX_DF)) {
		KM_ERR("unify key item is invalid\n");
		return -1;
	}

	return 0;
}

static struct key_item_t *unifykey_find_item_by_name(const char *name)
{
	struct key_item_t *pre_item;
    int i = 0;
    const unsigned cnt = unify_key_info.key_num;

    for (pre_item = unifykey_item; i < cnt; ++pre_item, ++i)
    {
        if (!strcmp(pre_item->name,name)) {
            return pre_item;
        }
    }
	return NULL;
}

enum key_manager_df_e keymanage_dts_get_key_fmt(const char *keyname)
{
	struct key_item_t *key_manage;
    enum key_manager_df_e keyValFmt = KEY_M_MAX_DF;

    if (!unify_key_info.key_flag) {
        KM_ERR("/unify not parsed yet!\n");
        return KEY_M_MAX_DF;
    }

	key_manage = unifykey_find_item_by_name(keyname);
	if (key_manage == NULL) {
		KM_ERR ("%s key name is not exist\n", keyname) ;
		return keyValFmt;
	}
	if (unifykey_item_verify_check(key_manage)) {
		KM_ERR ("%s key name is invalid\n", keyname) ;
		return keyValFmt;
	}

    keyValFmt = key_manage->datFmt;
	return keyValFmt;
}

//which device does the key stored in
enum key_manager_dev_e keymanage_dts_get_key_device(const char *keyname)
{
	struct key_item_t *key_manage;

    if (!unify_key_info.key_flag) {
        KM_ERR("/unify not parsed yet!\n");
        return KEY_M_MAX_DEV;
    }
	key_manage = unifykey_find_item_by_name(keyname);
	if (key_manage == NULL) {
		KM_ERR("%s key name is not exist\n",keyname);
		return KEY_M_MAX_DEV;
	}
	if (unifykey_item_verify_check(key_manage)) {
		KM_ERR("%s key name is invalid\n",keyname);
		return KEY_M_MAX_DEV;
	}

	return key_manage->dev;
}

const char* keymanage_dts_get_enc_type(const char* keyname)
{
	struct key_item_t *key_manage;

    if (!unify_key_info.key_flag) {
		KM_ERR("/unify not parsed yet!\n");
		return NULL;
	}
	key_manage = unifykey_find_item_by_name(keyname);
	if (key_manage == NULL) {
		KM_ERR("%s key name is not exist\n",keyname);
		return NULL;
	}

	return key_manage->encType;
}

const char* keymanage_dts_get_key_type(const char* keyname)
{
	struct key_item_t *key_manage;

    if (!unify_key_info.key_flag) {
        KM_ERR("/unify not parsed yet!\n");
        return NULL;
    }
	key_manage = unifykey_find_item_by_name(keyname);
	if (key_manage == NULL) {
		KM_ERR("%s key name is not exist\n",keyname);
		return NULL;
	}

	return key_manage->keyType;
}

char unifykey_get_efuse_version(void)
{
	char ver=0;

    if (!unify_key_info.key_flag) {
        KM_ERR("/unify not parsed yet!\n");
        return 0;
    }

	if (unify_key_info.efuse_version != -1) {
		ver = (char)unify_key_info.efuse_version;
	}
	return ver;
}

int unifykey_get_encrypt_type(void)
{
	return unify_key_info.encrypt_type;
}

static int unifykey_item_dt_parse(const void* dt_addr,int nodeoffset,int id,char *item_path)
{
	struct key_item_t *temp_item=NULL;
	char *propdata;
	struct fdt_property *prop;
	int count;

	temp_item = unifykey_item + id;

	propdata = (char*)fdt_getprop(dt_addr, nodeoffset, "key-encrypt", NULL);
	if (propdata) {
		count = strlen(propdata);
        if ( count > KEY_UNIFY_TYPE_LEN_MAX ) {
			KM_ERR("key-encrypt [%s] too long\n", propdata);
			return __LINE__;
		}
		memcpy(temp_item->encType, propdata, count);
	}

	propdata = (char*)fdt_getprop(dt_addr, nodeoffset, "key-name",NULL);
	if (!propdata) {
		printf("%s get key-name fail,%s:%d\n",item_path,__func__,__LINE__);
        return __LINE__;
	}

	count = strlen(propdata);
	if (count >= KEY_UNIFY_NAME_LEN) {
        KM_ERR("key-name strlen (%d) > max(%d) at key_%d\n", count, KEY_UNIFY_NAME_LEN - 1, id);
        return __LINE__;
	}
    memcpy(temp_item->name, propdata, count);
    temp_item->name[count] = 0;

	propdata = (char*)fdt_getprop(dt_addr, nodeoffset, "key-device",NULL);
	if (!propdata) {
		KM_ERR("%s get key-device fail at key_%d\n",item_path, id);
        return __LINE__;
	}

    if (strcmp(propdata,UNIFYKEY_DEVICE_EFUSEKEY) == 0) {
        temp_item->dev = KEY_M_EFUSE_NORMAL;
    }
    else if(strcmp(propdata,UNIFYKEY_DEVICE_SECURESKEY) == 0){
        temp_item->dev = KEY_M_SECURE_KEY;
    }
    else if(strcmp(propdata,UNIFYKEY_DEVICE_NORMAL) == 0){
        temp_item->dev = KEY_M_NORAML_KEY;
    }
    else{
        KM_ERR("key-device %s is unknown at key_%d\n", propdata, id);
        return __LINE__;
    }

	propdata = (char*)fdt_getprop((const void *)dt_addr, nodeoffset, "key-type",NULL);
	if (!propdata) //prop 'key-type' not configured, default to raw except special names
    {
        strcpy(temp_item->keyType, "raw");
	}
    else
    {
        const int keyTypeLen = strlen(propdata);
        if (keyTypeLen > KEY_UNIFY_TYPE_LEN_MAX) {
            KM_ERR("key[%s]cfg key-type[%s] sz %d > max %d\n", temp_item->name, propdata, keyTypeLen, KEY_UNIFY_TYPE_LEN_MAX);
            return __LINE__;
        }
        strcpy(temp_item->keyType, propdata);
    }

#if 0
	propdata = (char*)fdt_getprop((const void *)dt_addr, nodeoffset, "key-dataformat",NULL);
	if (!propdata) {
		KM_ERR("%s get key-dataformat fail at key_%d\n",item_path, id);
        return __LINE__;
	}
#endif

	prop = (struct fdt_property*)fdt_get_property((const void *)dt_addr,nodeoffset,"key-permit",NULL) ;
	if (!prop) {
		KM_ERR("%s get key-permit fail at  key_%d\n",item_path, id);
        return __LINE__;
	}

    temp_item->permit = 0;
    const int propLen = prop->len > 512 ? strnlen(prop->data, 512) : prop->len;
    if (fdt_stringlist_contains(prop->data, propLen, UNIFYKEY_PERMIT_READ)) {
        temp_item->permit |= KEY_M_PERMIT_READ;
    }
    if (fdt_stringlist_contains(prop->data, propLen, UNIFYKEY_PERMIT_WRITE)) {
        temp_item->permit |= KEY_M_PERMIT_WRITE;
    }
    if (fdt_stringlist_contains(prop->data, propLen, UNIFYKEY_PERMIT_DEL)) {
        temp_item->permit |= KEY_M_PERMIT_DEL;
    }

	temp_item->id = id;

    KM_DBG("key[%02d] keyname %s, %d\n", id, temp_item->name, temp_item->dev);

	return 0;
}

static int unifykey_item_create(const void* dt_addr,int num)
{
    int ret = 0;
    int i,nodeoffset;
    char item_path[100];

    for (i=0;i<num;i++)
    {
        sprintf(item_path, "/unifykey/key_%d", i);

        nodeoffset = fdt_path_offset (dt_addr, item_path) ;
        if (nodeoffset < 0) {
            KM_ERR(" dts: not find  node %s.\n",fdt_strerror(nodeoffset));
            return __LINE__;
        }

        ret = unifykey_item_dt_parse(dt_addr,nodeoffset, i, item_path);
        if (ret) {
            KM_ERR("Fail at parse %s\n", item_path);
            return __LINE__;
        }
    }

    //	printf("unifykey-num fact is %x\n",count);
    return 0;
}

//parse and cache the dts cfg
//TODO: check keys names has no duplicated
int keymanage_dts_parse(const void* dt_addr)
{
    int ret = 0;
	int nodeoffset;
	char *punifykey_num, *encrypt_type;

	if (fdt_check_header(dt_addr)!= 0) {
        KM_ERR("not a fdt at 0x%p\n", dt_addr);
        return __LINE__;
    }

	nodeoffset = fdt_path_offset(dt_addr, "/unifykey");
	if (nodeoffset < 0) {
		KM_ERR("dts: err(%s) in find /unifykey.\n",fdt_strerror(nodeoffset));
		return __LINE__;
	}

	unify_key_info.efuse_version = -1;
	punifykey_num = (char*)fdt_getprop((const void *)dt_addr, nodeoffset, "efuse-version",NULL);
	if (punifykey_num) {
		unify_key_info.efuse_version = be32_to_cpup((unsigned int*)punifykey_num);
		KM_MSG("efuse-version config is %x\n",unify_key_info.efuse_version);
	}

	unify_key_info.key_num = 0;
	punifykey_num = (char*)fdt_getprop((const void *)dt_addr, nodeoffset, "unifykey-num",NULL);
	if (punifykey_num) {
//		printf("unifykey-num config is %x\n",be32_to_cpup((unsigned int*)punifykey_num));
		unify_key_info.key_num = be32_to_cpup((unsigned int*)punifykey_num);
	}

	unify_key_info.encrypt_type = -1;
	encrypt_type = (char*)fdt_getprop((const void *)dt_addr, nodeoffset, "unifykey-encrypt",NULL);
	if (encrypt_type) {
		unify_key_info.encrypt_type = be32_to_cpup((unsigned int*)encrypt_type);
	}

	if (unify_key_info.key_num <= 0) {
		KM_ERR("unifykey-num is not configured\n");
        return __LINE__;
	}
    if (unify_key_info.key_num > 32) {
        KM_ERR("Cfg key_num is %d > 32,pls check!\n", unify_key_info.key_num);
        return __LINE__;
    }

    if (unifykey_item) {
        free(unifykey_item);
    }
    const unsigned keyInfBufLen = unify_key_info.key_num * sizeof(struct key_item_t);
    unifykey_item = (struct key_item_t*)malloc(keyInfBufLen);
    memset(unifykey_item, 0 , keyInfBufLen);

    ret = unifykey_item_create(dt_addr,unify_key_info.key_num);
    unify_key_info.key_flag = ret ? 0 : 1;

	return ret;
}

