blob: 30e847309186a706103757465f686cbe279eaf5c [file] [log] [blame]
/*
***********************************************************
*/
#include <common.h>
#include <asm/io.h>
#include <asm/string.h>
#include <sdio.h>
#include <image.h>
#include "efuse.h"
#include "drv_rsa.h"
#include "drv_hash.h"
#define E_N_LEN 256
#define HASH_LEN 128
/*
******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
* Output:
* Returns:
* Others:
*******************************************************************************
*/
static u8 data_cmp_word(u32* src, u32* dst, u32 cnt)
{
u32 i;
for(i = 0; i < cnt; i++)
{
if(src[i] != dst[i])
{
return 1;
}
}
return 0;
}
/*
******************************************************************************
* Function:
* Description:
* Parameters:
* Input:
* Output:
* Returns:
* Others:
*******************************************************************************
*/
int SecureVerify(u32 puiSdrmStartAddr)
{
u32 uiLen = 0;
u32 uiRet = -1;
image_header_t *puiLegacyImgAddr = NULL;
sImageNewHeader *psImageHeader = NULL;
efuse_struct *psEfuseInfo = NULL;
u32 *puiDataLoadAddr = NULL;
u32 *puiArrHASH = NULL;
u32 uiHashResArr[4] = {0};
u32 uiHashResLen = 0;
u32 uiHashVerifySize = 0;
u32 uiRsaResArr[32] = {0};
u32 puiArrPubKey[64] = {0};
int guiEfuseStatus = 1;
int default_flag = 1;
T_Rsa_Paramter sRSAInput;
u32 *puiRsaResAddr = NULL;
if(0 == puiSdrmStartAddr)
{
return -1;
}
psImageHeader = (sImageNewHeader *)puiSdrmStartAddr;
puiLegacyImgAddr = (image_header_t *)(puiSdrmStartAddr + sizeof(sImageNewHeader));
uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);
guiEfuseStatus = get_secure_verify_status();
if(guiEfuseStatus == 0) //efuse secure verify.
psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
else
{
default_flag = 0;
#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
return 0;
#endif
}
/*
* 0. ¼ì²éPubKeyÊÇ·ñ±»´Û¸Ä¡£
* - ¶ÔPubKeyÃ÷ÎĽøÐÐHASH_MD5ÔËË㣬
* ²¢ÇÒÓëefuseÖб£´æµÄpuk_hash±È½Ï¡£
* - ±È½ÏÊý¾ÝÏàͬ£¬·µ»Ø0£»
* - ²»Í¬£¬·µ»Ø1¡£
*/
uiLen = E_N_LEN; //¹«Ô¿EºÍN£¬¹²256byte³¤¶È¡£
memcpy((puiArrPubKey+31), psImageHeader->uiPubKeyRsaE, 4);
memcpy((puiArrPubKey+32), psImageHeader->uiPubKeyRsaN, 128);
uiRet = Hash_Calculate(HASH_MODE_MD5,
HASH_SMALL_ENDIAN,
puiArrPubKey,
uiLen,
NULL,
0,
uiHashResArr,
&uiHashResLen);
if(uiRet != 0)
{
return 1;
}
if(1 == default_flag)
{
if(data_cmp_word((u32 *)psEfuseInfo->puk_hash,
uiHashResArr, uiHashResLen))
{
//printf("Puk hash verify fail!\n");
printf("2\n");
return 2;
}
}
puiArrHASH = psImageHeader->uiHashY;
/*
* 1. ÀûÓù«Ô¿¶ÔuiHashY'½øÐнâÃÜ£¬µÃµ½1024bit½á¹û¡£
*/
sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;
sRSAInput.udNbitLen = 1024;
sRSAInput.udEbitLen = 1024;
sRSAInput.pudInputM = puiArrHASH;
sRSAInput.pudInputE = puiArrPubKey;
sRSAInput.pudInputN = (puiArrPubKey + 32);
sRSAInput.pudOutputP = uiRsaResArr;
uiRet = Rsa_Calculate(sRSAInput);
if(uiRet != 0)
{
//printf("Rsa_Calculate fail!\n");
printf("3\n");
return 3;
}
//È¡×îºó4×Ö½Ú×÷ΪPubKey½âÃܺóµÄHASH_MD5Öµ¡£
puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);
/*
* 2. ¼ÆËãÏÂÒ»¼¶¾µÏñµÄHASH_MD5Öµ¡£
* - ¶ÔLegacyImage(64 BytesµÄÍ·ÐÅÏ¢+°æ±¾Çø)½øÐÐhash¼ÆË㣬
* ²¢ÇÒÓëPubKeyÑéÇ©µÄ½á¹û½øÐбȽϡ£
*/
uiLen = uiHashVerifySize;
puiDataLoadAddr = (u32 *)(___htonl(puiLegacyImgAddr->ih_load)
- sizeof(image_header_t));
/* Cleanup Output Buffer. */
uiHashResLen = 0;
memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));
uiRet = Hash_Calculate(HASH_MODE_MD5,
HASH_SMALL_ENDIAN,
puiDataLoadAddr,
uiLen,
NULL,
0,
uiHashResArr,
&uiHashResLen);
if(uiRet != 0)
{
//printf("Hash_Calculate Fail!\n");
printf("4\n");
return 4;
}
if(data_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))
{
//printf("SignImage Verify Fail!\n");
printf("5\n");
return 5;
}
return 0;
}