/*
 * 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/storage_if.h>
#include <amlogic/amlkey_if.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_key_read(storagekey_info.buffer,
		storagekey_info.size,
		&actual_size);
	if (ret) {
		/* memset head info for bl31 */
		memset(storagekey_info.buffer, 0, SECUESTORAGE_HEAD_SIZE);
		ret = 0;
		goto _out;
	}

	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_key_write(storagekey_info.buffer,
				storagekey_info.size,
				&actual_size);
			if (ret) {
				printf("%s() %d, store_key_write fail\n",
					__func__, __LINE__);
				retval = 0;
			}
		}
	}
_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;
	uint32_t actual_size;

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

	return ret;
}

