blob: ded4a51f2a94b1499e31ad32359ffa6f878f7361 [file] [log] [blame]
/*
* \file km_efuse_key.c
* \brief efuse key ops for key manage
*
* \version 1.0.0
* \date 15/06/30
* \author Sam.Wu <yihui.wu@amlgic.com>
*
* Copyright (c) 2015 Amlogic. All Rights Reserved.
*
*/
#include "key_manage_i.h"
#include <asm/arch/secure_apb.h>
#include <asm/io.h>
#define SECURE_BOOT_KEY_NAME "secure_boot_set"
extern int efuse_usr_api_init_dtb(const char* dt_addr);
extern int efuse_usr_api_get_cfg_key_size(const char* keyname, unsigned* pSz);
extern int efuse_usr_api_write_key(const char* keyname, const void* keydata, const unsigned dataSz);
extern int efuse_usr_api_read_key(const char* keyname, void* databuf, const unsigned bufSz);
int keymanage_efuse_init(const char *buf, int len)
{
char ver;
int ret = 0;
const char* dtbLoadAddr = getenv("dtb_mem_addr");
if (!dtbLoadAddr) {
setenv("dtb_mem_addr", simple_itoa(CONFIG_SYS_SDRAM_BASE + (16U<<20)));
}
dtbLoadAddr = (char*)simple_strtoul(dtbLoadAddr, NULL, 0);
ret = efuse_usr_api_init_dtb(dtbLoadAddr);
if (ret) {
KM_ERR("efuse init failed\n");
return __LINE__;
}
ver = unifykey_get_efuse_version();
if (ver == 0) {
KM_DBG("efuse version not cfg\n");
return 0;
}
//TODO: program the efuse version
return ret;
}
int keymange_efuse_exit(void)
{
return 0;
}
//must be hexdata if stored in efuse
int keymanage_efuse_write(const char *keyname, const void* keydata, unsigned int datalen)
{
int ret = 0;
if (!strcmp(SECURE_BOOT_KEY_NAME, keyname))
{
char _cmdbuf[96];
sprintf(_cmdbuf, "efuse %s %p", keyname, keydata);
ret = run_command(_cmdbuf, 0);;
}
else
{
ret = efuse_usr_api_write_key(keyname, keydata, datalen);
}
return ret;
}
ssize_t keymanage_efuse_size(const char* keyname)
{
int ret = 0;
unsigned cfgSz = 0;
ret = efuse_usr_api_get_cfg_key_size(keyname, &cfgSz);
if (ret || !cfgSz) {
KM_ERR("Fail at get cfg size for efuse key[%s]\n", keyname);
return 0;
}
return cfgSz;
}
int keymanage_efuse_exist(const char* keyname)
{
if (!strcmp(SECURE_BOOT_KEY_NAME, keyname))
{
const unsigned long cfg10 = readl(AO_SEC_SD_CFG10);
KM_MSG("cfg10=0x%lX\n", cfg10);
return ( cfg10 & (0x1<< 4) );
}
else
{
int ret = 0;
const ssize_t cfgSz = keymanage_efuse_size(keyname);
char* databuf = NULL;
int isEmpty = 1;
int i = 0;
databuf = (char*)malloc(cfgSz);
if (!databuf) {
KM_ERR("Fail to alloc bufsz 0x%x for key %s\n", (unsigned)cfgSz, keyname);
return 0;
}
ret = keymanage_efuse_read(keyname, databuf, cfgSz);
if (ret) {
KM_ERR("Fail at read key[%s]\n", keyname);
goto _exit;
}
for (i = 0; i < cfgSz && isEmpty; ++i) {
isEmpty = !databuf[i];
}
_exit:
free(databuf);
return !isEmpty;
}
return __LINE__;
}
int keymanage_efuse_query_can_read(const char* keyname)
{
if (!strcmp(SECURE_BOOT_KEY_NAME, keyname))
{
return 0;
}
else
{
return 1;//user space always can be read
}
}
//data format is hexdata
int keymanage_efuse_read(const char *keyname, void* databuf, const unsigned bufSz)
{
int ret = 0;
unsigned cfgSz = 0;
cfgSz = keymanage_efuse_size(keyname);
if (cfgSz > bufSz) {
KM_ERR("buf sz 0x%x < dts cfg sz 0x%x\n", bufSz, cfgSz);
return __LINE__;
}
ret = efuse_usr_api_read_key(keyname, databuf, cfgSz);
return ret;
}