blob: d0b57d38427a4429d4df6d6474e255c8921f5da4 [file] [log] [blame]
/*
* \file sdc_bootPart_license.c
* \brief
*
* \version 1.0.0
* \date 2015/3/10
* \author Sam.Wu <yihui.wu@amlgic.com>
*
* Copyright (c) 2015 Amlogic. All Rights Reserved.
*
*/
#include "../optimus_sdc_burn_i.h"
#include "sdc_bootPart_license.h"
#include <crc.h>
COMPILE_TYPE_CHK(AML_BOOT_PART_KEY_HEAD_SZ == sizeof(BootPartKeyInf_head_t), _aa1);
COMPILE_TYPE_CHK(AML_BOOT_PART_KEY_ITEM_SZ == sizeof(BootPartKeyInf_Item_t), _aa2);
#define _OPT_BOOT_PART_LIC_INFO_LOADADDR (OPTIMUS_DOWNLOAD_SPARSE_INFO_FOR_VERIFY)
#define _pOptBootPartLicHeadInf (BootPartKeyInf_head_t*)(_OPT_BOOT_PART_LIC_INFO_LOADADDR)
//Load boot part license info from external emmc to memory
//As "mmc read" is slow, I load it from external mmc only once
int optimus_sdc_bootPart_lic_download(void)
{
const unsigned maxLen = 2U<<20;//
const unsigned firstReadLen = 2U<<10;//2K
const char* _cmdStr = "mmc read 1 0x%x, 0x%x 0x%x";
BootPartKeyInf_head_t* pBootPartKeyInfHead = _pOptBootPartLicHeadInf;
char _cmdBuf[96];
int rc = 0;
//1, Read from _OPT_BOOT_PART_LIC_INFO_LOADADDR
rc = run_command("mmcinfo", 0);
if (rc) {
DWN_ERR("Fail to init external sdcard\n");
return __LINE__;
}
memset(pBootPartKeyInfHead, 0, AML_BOOT_PART_KEY_HEAD_SZ + AML_BOOT_PART_KEY_ITEM_SZ * 64);
sprintf(_cmdBuf, _cmdStr, _OPT_BOOT_PART_LIC_INFO_LOADADDR, AML_BOOT_PART_KEY_HEAD_OFFSET, firstReadLen);
DWN_MSG("cmd[%s]\n", _cmdBuf);
rc = run_command(_cmdBuf, 0);
if (rc) {
DWN_ERR("Fail in cmd[%s]\n", _cmdBuf);
return __LINE__;
}
rc = (AML_BOOT_PART_KEY_HEAD_VERSION == pBootPartKeyInfHead->version)
&& (AML_BOOT_PART_KEY_HEAD_MAGIC == pBootPartKeyInfHead->magic);
if (!rc)
{
DWN_MSG("Ver[0x%x] or magic[0x%8x] error\n",
pBootPartKeyInfHead->version, pBootPartKeyInfHead->magic);
//Create the image header
pBootPartKeyInfHead->magic = AML_BOOT_PART_KEY_HEAD_MAGIC;
pBootPartKeyInfHead->version = AML_BOOT_PART_KEY_HEAD_VERSION;
pBootPartKeyInfHead->alignSz = AML_BOOT_PART_ALIGN_SZ;
pBootPartKeyInfHead->imgSz = sizeof(BootPartKeyInf_head_t);
pBootPartKeyInfHead->imgItemNum = 0;
return 0;
}
const unsigned totalLen = pBootPartKeyInfHead->imgSz;
if (totalLen > maxLen) {
DWN_ERR("totalLen=0x%x > max=0x%x\n", totalLen, maxLen);
return __LINE__;
}
DWN_MSG("totalLen=0x%x\n", totalLen);
const unsigned genCrc = crc32(0, (u8*)&pBootPartKeyInfHead->magic,
totalLen - sizeof(unsigned int));
if (genCrc != pBootPartKeyInfHead->hcrc) {
DWN_ERR("genCrc(0x%x) != savedCrc(0x%x), pls clear the card using tool\n",
genCrc, pBootPartKeyInfHead->hcrc);
return __LINE__;
}
DWN_MSG("genCrc=0x%x\n", genCrc);
if (totalLen > firstReadLen)
{
const unsigned leftLen = totalLen - firstReadLen;
sprintf(_cmdBuf, _cmdStr, _OPT_BOOT_PART_LIC_INFO_LOADADDR,
AML_BOOT_PART_KEY_HEAD_OFFSET + firstReadLen, leftLen);
DWN_MSG("cmd[%s]\n", _cmdBuf);
rc = run_command(_cmdBuf, 0);
if (rc) {
DWN_ERR("Fail in cmd[%s]\n", _cmdBuf);
return __LINE__;
}
}
return 0;
}
int optimus_sdc_bootPart_lic_upload(void)
{
const char* _cmdStr = "mmc write 1 0x%x, 0x%x 0x%x";
BootPartKeyInf_head_t* pBootPartKeyInfHead = _pOptBootPartLicHeadInf;
char _cmdBuf[96];
int rc = 0;
rc = (AML_BOOT_PART_KEY_HEAD_VERSION == pBootPartKeyInfHead->version)
&& (AML_BOOT_PART_KEY_HEAD_MAGIC == pBootPartKeyInfHead->magic);
if (!rc) {
DWN_MSG("Ver[0x%x] or magic[0x%8x] error\n",
pBootPartKeyInfHead->version, pBootPartKeyInfHead->magic);
return __LINE__;
}
rc = run_command("mmcinfo", 0);
if (rc) {
DWN_ERR("Fail to init external sdcard\n");
return __LINE__;
}
DWN_MSG("imgSz=0x%x\n", pBootPartKeyInfHead->imgSz);
//Update crc32 in image header
const unsigned genCrc = crc32(0, (u8*)&pBootPartKeyInfHead->magic,
pBootPartKeyInfHead->imgSz - sizeof(unsigned int));
pBootPartKeyInfHead->hcrc = genCrc;
DWN_MSG("genCrc=0x%x\n", genCrc);
const unsigned totalLen = pBootPartKeyInfHead->imgSz;
sprintf(_cmdBuf, _cmdStr, _OPT_BOOT_PART_LIC_INFO_LOADADDR, AML_BOOT_PART_KEY_HEAD_OFFSET, totalLen);
rc = run_command(_cmdBuf, 0);
if (rc) {
DWN_ERR("Fail in cmd[%s]\n", _cmdBuf);
return __LINE__;
}
return 0;
}
//* keyInfAddr is sizeof the key info
//
//*/
int optimus_sdc_bootPart_lic_get_key_infdata(const char* keyName, void** keyInfAddr)
{
BootPartKeyInf_head_t* pBootPartKeyInfHead = _pOptBootPartLicHeadInf;
BootPartKeyInf_Item_t* pBootPartKeyItemInf = (BootPartKeyInf_Item_t*)(pBootPartKeyInfHead + 1);
const unsigned itemCnt = pBootPartKeyInfHead->imgItemNum;
int rc = 0;
int itemIndex = 0;
*keyInfAddr = NULL;
DWN_MSG("Get lic info for key[%s]\n", keyName);
//2, check _pOptBootPartLicHeadInf
rc = (AML_BOOT_PART_KEY_HEAD_VERSION == pBootPartKeyInfHead->version)
&& (AML_BOOT_PART_KEY_HEAD_MAGIC == pBootPartKeyInfHead->magic);
if (!rc) {
DWN_MSG("Ver[0x%x] or magic[0x%8x]\n",
pBootPartKeyInfHead->version, pBootPartKeyInfHead->magic);
return 0;
}
//3, find the item and return the count, return 0 if not found
for(itemIndex = 0; itemIndex < itemCnt; ++itemIndex,
pBootPartKeyItemInf = (BootPartKeyInf_Item_t*)(pBootPartKeyItemInf->nextItemInfOffset + (void*)_OPT_BOOT_PART_LIC_INFO_LOADADDR))
{
const unsigned char* theKeyName = pBootPartKeyItemInf->keyName;
rc = memcmp(keyName, theKeyName, strlen(keyName));
if (rc) continue;
*keyInfAddr = ++pBootPartKeyItemInf;
return 0;
}
return 0;
}
//add an key info item if any, or update it
int optimus_sdc_bootPart_lic_update_key_inf(const char* keyName, unsigned char* keyVal, unsigned int keyLen)
{
BootPartKeyInf_head_t* pBootPartKeyInfHead = _pOptBootPartLicHeadInf;
BootPartKeyInf_Item_t* pBootPartKeyItemInf = (BootPartKeyInf_Item_t*)(pBootPartKeyInfHead + 1);
const unsigned itemCnt = pBootPartKeyInfHead->imgItemNum;
int rc = 0;
int itemIndex = 0;
DWN_MSG("update lic info for key[%s]\n", keyName);
//2, check _pOptBootPartLicHeadInf
rc = (AML_BOOT_PART_KEY_HEAD_VERSION == pBootPartKeyInfHead->version)
&& (AML_BOOT_PART_KEY_HEAD_MAGIC == pBootPartKeyInfHead->magic);
if (!rc) {
DWN_MSG("Ver[0x%x] or magic[0x%8x]\n",
pBootPartKeyInfHead->version, pBootPartKeyInfHead->magic);
return __LINE__;
}
BootPartKeyInf_Item_t* prevItemInf = NULL;
//3, find the item and return the count, return 0 if not found
for(itemIndex = 0; itemIndex < itemCnt; ++itemIndex,
prevItemInf = pBootPartKeyItemInf,
pBootPartKeyItemInf = (BootPartKeyInf_Item_t*)(pBootPartKeyItemInf->itemSz + (unsigned long)pBootPartKeyItemInf))
{
const unsigned char* theKeyName = pBootPartKeyItemInf->keyName;
rc = memcmp(keyName, theKeyName, strlen(keyName));
if (rc) continue;
if (AML_BOOT_PART_KEY_ITEM_MAGIC != pBootPartKeyItemInf->magic) {
DWN_ERR("Excp: item magic 0x%x eror, must be 0x%x\n",
pBootPartKeyItemInf->magic, AML_BOOT_PART_KEY_ITEM_MAGIC);
return __LINE__;
}
//write key founded, update the total data
DWN_MSG("Find item at index %d\n", itemIndex);
if (pBootPartKeyItemInf->itemSz != keyLen + sizeof(BootPartKeyInf_Item_t)) {
DWN_ERR("Excp: oldlen %d != newlen %d\n", pBootPartKeyItemInf->itemSz, keyLen);
return __LINE__;
}
return 0;//To simple it just return
}
if (prevItemInf)
{
prevItemInf->nextItemInfOffset = (unsigned long)pBootPartKeyItemInf - _OPT_BOOT_PART_LIC_INFO_LOADADDR;
}
if (itemIndex != itemCnt) {
DWN_ERR("Exp:itemIndex[%d] != itemCnt[%d]\n", itemIndex, itemCnt);
return __LINE__;
}
memcpy(pBootPartKeyItemInf + 1, keyVal, keyLen);
//update item info
pBootPartKeyItemInf->itemIndex = itemIndex;
pBootPartKeyItemInf->itemSz = keyLen + sizeof(BootPartKeyInf_Item_t);
memcpy(pBootPartKeyItemInf->keyName, keyName, strlen(keyName));
pBootPartKeyItemInf->version = AML_BOOT_PART_KEY_ITEM_VERSION;
pBootPartKeyItemInf->magic = AML_BOOT_PART_KEY_ITEM_MAGIC;
//
//Update head info
pBootPartKeyInfHead->imgSz += keyLen;
++pBootPartKeyInfHead->imgItemNum;
return 0;
}