/*
 * drivers/storagekey/storagekey.c
 *
 * Copyright (C) 2015 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/* extern from bl31 */
/*
 * when RET_OK
 * query: retval=1: key exsit,=0: key not exsit；
 * tell: retvak = key size
 * status: retval=1: secure, retval=0: non-secure

 */

#include <common.h>
#include <linux/types.h>
#include <amlogic/secure_storage.h>
#include <amlogic/amlkey_if.h>
#include <amlogic/storage.h>
#ifdef CONFIG_STORE_COMPATIBLE
#include <partition_table.h>
#endif

/* key buffer status */
/* bit0, dirty flag*/
#define KEYBUFFER_CLEAN		(0 << 0)
#define KEYBUFFER_DIRTY		(1 << 0)
#define SECUESTORAGE_HEAD_SIZE		(256)
#define SECUESTORAGE_WHOLE_SIZE		(0x40000)

struct storagekey_info_t {
	uint8_t * buffer;
	uint32_t size;
	uint32_t status;
};

static struct storagekey_info_t storagekey_info = {
	.buffer = NULL,
	/* default size */
	.size = SECUESTORAGE_WHOLE_SIZE,
	.status = KEYBUFFER_CLEAN,
};

/**
 *1.init
 * return ok 0, fail 1
 */
int32_t amlkey_init(uint8_t *seed, uint32_t len, int encrypt_type)
{
	int32_t ret = 0;
	uint32_t buffer_size, actual_size;

	/* do nothing for now*/
	printf("%s() enter!\n", __func__);
	if (storagekey_info.buffer != NULL) {
		printf("%s() %d: already init!\n", __func__, __LINE__);
		goto _out;
	}

	/* get buffer from bl31 */
	storagekey_info.buffer = secure_storage_getbuffer(&buffer_size);
	if (storagekey_info.buffer == NULL) {
		printf("%s() %d: can't get buffer from bl31!\n",
			__func__, __LINE__);
		ret = -1;
		goto _out;
	}

	if (encrypt_type == -1)
		encrypt_type = 0;
	secure_storage_set_enctype(encrypt_type);

	/* full fill key infos from storage. */
	ret = store_rsv_read("key", storagekey_info.size, storagekey_info.buffer);
	if (ret) {
		/* memset head info for bl31 */
		memset(storagekey_info.buffer, 0, SECUESTORAGE_HEAD_SIZE);
		ret = 0;
		goto _out;
	}
    actual_size = storagekey_info.size;

	storagekey_info.size = actual_size;
	secure_storage_notifier_ex(actual_size, 0);

	storagekey_info.buffer = secure_storage_getbuffer(&buffer_size);
	if (buffer_size != actual_size) {
		ret = -1;
		goto _out;
	}

#ifdef CONFIG_STORE_COMPATIBLE
	info_disprotect &= ~DISPROTECT_KEY;  //protect
#endif
_out:
	return ret;
}

/**
 *2. query if the key already programmed
 * return: exsit 1, non 0
 */
int32_t amlkey_isexsit(const uint8_t * name)
{
	int32_t ret = 0;
	uint32_t retval;

	if ( NULL == name ) {
		printf("%s() %d, invalid key ", __func__, __LINE__);
		return 0;
	}

	ret = secure_storage_query((uint8_t *)name, &retval);
	if (ret) {
		printf("%s() %d: ret %d\n", __func__, __LINE__, ret);
		retval = 0;
	}

	return (int32_t)retval;
}

static int32_t amlkey_get_attr(const uint8_t * name)
{
	int32_t ret = 0;
	uint32_t retval;

	if ( NULL == name ) {
		printf("%s() %d, invalid key ", __func__, __LINE__);
		return 0;
	}

	ret = secure_storage_status((uint8_t *)name, &retval);
	if (ret) {
		printf("%s() %d: ret %d\n", __func__, __LINE__, ret);
		retval = 0;
	}

	return (int32_t)(retval);
}

/**
 * 3.1 query if the prgrammed key is secure. key must exsit!
 * return secure 1, non 0;
 */
int32_t amlkey_issecure(const uint8_t * name)
{
	return (amlkey_get_attr(name)&UNIFYKEY_ATTR_SECURE_MASK);
}

/**
 * 3.2 query if the prgrammed key is encrypt
 * return encrypt 1, non-encrypt 0;
 */
int32_t amlkey_isencrypt(const uint8_t * name)
{
	return (amlkey_get_attr(name)&UNIFYKEY_ATTR_ENCRYPT_MASK);
}
/**
 * 4. actual bytes of key value
 *  return actual size.
 */
ssize_t amlkey_size(const uint8_t *name)
{
	ssize_t size = 0;
	int32_t ret = 0;
	uint32_t retval;

	if ( NULL == name ) {
		printf("%s() %d, invalid key ", __func__, __LINE__);
		return 0;
	}

	ret = secure_storage_tell((uint8_t *)name, &retval);
	if (ret) {
		printf("%s() %d: ret %d\n", __func__, __LINE__, ret);
		retval = 0;
	}
	size = (ssize_t)retval;
	return size;
}

/**
 *5. read non-secure key in bytes, return bytes readback actully.
 * return actual size read back.
 */
ssize_t amlkey_read(const uint8_t *name, uint8_t *buffer, uint32_t len)
{
	int32_t ret = 0;
	ssize_t retval = 0;
	uint32_t actul_len;

	if ( NULL == name ) {
		printf("%s() %d, invalid key ", __func__, __LINE__);
		return 0;
	}
	ret = secure_storage_read((uint8_t *)name, buffer, len, &actul_len);
	if (ret) {
		printf("%s() %d: return %d\n", __func__, __LINE__, ret);
		retval = 0;
		goto _out;
	}
	retval = actul_len;
_out:
	return retval;
}

/**
 * 6.write secure/non-secure key in bytes , return bytes readback actully
 * attr: bit0, secure/non-secure;
 *		 bit8, encrypt/non-encrypt;
 * return actual size write down.
 */
ssize_t amlkey_write(const uint8_t *name, uint8_t *buffer, uint32_t len, uint32_t attr)
{
	int32_t ret = 0;
	ssize_t retval = 0;
	uint32_t actual_size;

	if ( NULL == name ) {
		printf("%s() %d, invalid key ", __func__, __LINE__);
		return retval;
	}
	ret = secure_storage_write((uint8_t *)name, buffer, len, attr);
	if (ret) {
		printf("%s() %d: return %d\n", __func__, __LINE__, ret);
		retval = 0;
		goto _out;
	} else {
		retval = (ssize_t)len;
		/* write down! */
		if (storagekey_info.buffer != NULL) {
            ret = store_rsv_write("key", storagekey_info.size, storagekey_info.buffer);
			if (ret) {
				printf("%s() %d, store_key_write fail\n",
					__func__, __LINE__);
				retval = 0;
			}
            actual_size = storagekey_info.size;

			/* Should we return |actual_size| here? For now just log. */
			if (actual_size != retval) {
				printf("%s() %d: key size mismatch? retval %zd, actual %u\n",
					__func__, __LINE__, retval, actual_size);
			}
		}
	}
_out:
	return retval;
}
/**
 * 7. get the hash value of programmed secure key | 32bytes length, sha256
 * return success 0, fail -1
 */
int32_t amlkey_hash_4_secure(const uint8_t * name, uint8_t * hash)
{
	int32_t ret = 0;

	ret = secure_storage_verify((uint8_t *)name, hash);

	return ret;
}

/**
 * 7. del key by name
 * return success 0, fail -1
 */
int32_t amlkey_del(const uint8_t * name)
{
	int32_t ret = 0;

	ret = secure_storage_remove((uint8_t *)name);
	if ((ret == 0) && (storagekey_info.buffer != NULL)) {
		/* flush back */
        ret = store_rsv_write("key", storagekey_info.size, storagekey_info.buffer);
		if (ret) {
			printf("%s() %d, store_key_write fail\n",
				__func__, __LINE__);
		}
	} else {
		printf("%s() %d, remove key fail\n",
			__func__, __LINE__);
	}

	return ret;
}

