523 lines
17 KiB
C
523 lines
17 KiB
C
/*******************************************************************************
|
|
* DISCLAIMER
|
|
* This software is supplied by Renesas Electronics Corporation and is only
|
|
* intended for use with Renesas products. No other uses are authorized. This
|
|
* software is owned by Renesas Electronics Corporation and is protected under
|
|
* all applicable laws, including copyright laws.
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
|
|
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
|
|
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
|
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
|
|
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
|
|
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
|
|
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
|
|
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
* Renesas reserves the right, without notice, to make changes to this software
|
|
* and to discontinue the availability of this software. By using this software,
|
|
* you agree to the additional terms and conditions found by accessing the
|
|
* following link:
|
|
* http://www.renesas.com/disclaimer
|
|
* Copyright 2018-2025 Renesas Electronics Corporation All rights reserved.
|
|
*******************************************************************************/
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
* DESCRIPTION : ICUMIF control function
|
|
******************************************************************************/
|
|
/******************************************************************************
|
|
* @file secure_boot.c
|
|
* - Version : 0.08
|
|
* @brief ICUMIF controller.
|
|
* .
|
|
*****************************************************************************/
|
|
/******************************************************************************
|
|
* History : DD.MM.YYYY Version Description
|
|
* : 16.06.2022 0.01 First Release
|
|
* : 22.07.2022 0.02 Change CMAC address settings
|
|
* Added include file
|
|
* Changed for Warning measures
|
|
* : 31.10.2022 0.03 License notation change.
|
|
* : 07.12.2022 0.04 Warning support when log output is disabled
|
|
* : 15.02.2023 0.05 Added final_hash_cmp function.
|
|
* : 04.04.2023 0.06 Removed stdio.h.
|
|
* : 21.08.2023 0.07 Add support for V4M.
|
|
* : 14.01.2024 0.08 Add parameter setting process for RTOS#1/#2.
|
|
*****************************************************************************/
|
|
#include "log.h"
|
|
#include "timer.h"
|
|
#include "r_icumif_api.h"
|
|
#include "r_icumif_pub.h"
|
|
#include "icum_d_comm_pe_pub.h"
|
|
#include "shared.h"
|
|
#include "image_load.h"
|
|
#include "secure_boot.h"
|
|
#include "rst_register.h"
|
|
|
|
#define LCS_CM (0x00000000U) /* CM */
|
|
#define LCS_DM (0x00000001U) /* DM */
|
|
#define LCS_SD (0x00000003U) /* SD */
|
|
#define LCS_SE (0x00000005U) /* SE */
|
|
#define LCS_FA (0x00000007U) /* FA */
|
|
|
|
#define RST_MODEMR0_MD5 (0x00000020U)
|
|
|
|
#define CX_CMAC_COPY (4U)
|
|
#define CX_ICUMIF_STATUS (0x1000F800UL)
|
|
#define CX_SIZEOF_CNT (4U)
|
|
#define CX_CMAC_SIZE (16U)
|
|
|
|
/* Definitions for hash_cmp */
|
|
#define HASH_CMP_NUM (0x2U) /* The number of hash check images */
|
|
#define HASH_SIZE (32U) /* Hash size (32-bytes) */
|
|
#define CR52_IPL_HASH_SAVE_ADDR (0xE635FF40U) /* Hash save address for CR52 IPL */
|
|
#define SECURE_FW_HASH_SAVE_ADDR (0xE635FFC0U) /* Hash save address for Secure FW */
|
|
|
|
static void secureboot_memset(void *buff, uint32_t data, uint32_t cnt);
|
|
static void secureboot_service(r_icumif_isd_t *p_ISD);
|
|
|
|
void secureboot_init(void)
|
|
{
|
|
int32_t r_errno;
|
|
volatile uint32_t *status;
|
|
|
|
status = (volatile uint32_t *)R_ICUMIF_GetStatus();
|
|
|
|
/* Wait until the ICU-M system intialization is complete */
|
|
while(true)
|
|
{
|
|
if((*status & CX_ICUMIF_STATUS) != 0UL)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
micro_wait(100U); /* 100 micro sec */
|
|
}
|
|
}
|
|
|
|
r_errno = R_ICUMIF_Init((uint32_t *)((uintptr_t)MEM_INFO_SERVICEQUE_1_ADDR));
|
|
if(r_errno != R_ICUMIF_ER_OK)
|
|
{
|
|
ERROR("R_ICUMIF_Init:Error code = (0x%x).\n", (unsigned int)r_errno);
|
|
panic;
|
|
}
|
|
|
|
}
|
|
/* End of function secureboot_init(void) */
|
|
|
|
uint32_t judge_bootmode(void)
|
|
{
|
|
uint32_t *p_lcs;
|
|
r_icumif_isd_t *p_ISD;
|
|
uint32_t md;
|
|
uint32_t is_verify = SECURE_BOOT;
|
|
|
|
__attribute__((unused))const char *lcs_name[8U] = {
|
|
[LCS_CM] = "CM",
|
|
[LCS_DM] = "DM",
|
|
[LCS_SD] = "SD",
|
|
[LCS_SE] = "SE",
|
|
[LCS_FA] = "FA",
|
|
};
|
|
|
|
secureboot_memset(ISD_BUFFER, 0U, SIZE_OF_ISD_BUFFER);
|
|
secureboot_memset(LCS_BUFFER, 0U, SIZE_OF_LCS_BUFFER);
|
|
|
|
/* initialize the global icum service header */
|
|
p_ISD = (r_icumif_isd_t *)ISD_BUFFER;
|
|
p_lcs = (uint32_t *)LCS_BUFFER;
|
|
|
|
p_ISD->service_id = SERVICE_00_SECURE_BOOT_API;
|
|
p_ISD->ptr.p_callbackfunc = NULL;
|
|
p_ISD->job_id = 0U;
|
|
p_ISD->res_nointerrupt = R_ICUMIF_REQRES_NOINTERRPUT;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.boot_api_id = ROM_GET_LCS;
|
|
p_ISD->prm.SECURE_BOOT_API.api.get_lcs.ptr.p_lcs = p_lcs;
|
|
p_ISD->prm.SECURE_BOOT_API.api.get_lcs.lcs_size_in_bytes = SIZE_OF_LCS_BUFFER;
|
|
|
|
/* trigger the service request */
|
|
secureboot_service(p_ISD);
|
|
|
|
if(ROMAPI_OK != p_ISD->prm.SECURE_BOOT_API.api_return_value)
|
|
{
|
|
ERROR("SECURE_BOOT_API:Error code = (0x%x).\n",
|
|
(unsigned int)p_ISD->prm.SECURE_BOOT_API.api_return_value);
|
|
panic;
|
|
}
|
|
else
|
|
{
|
|
/* LCM Status check */
|
|
if(( LCS_CM != *p_lcs)
|
|
&& ( LCS_DM != *p_lcs)
|
|
&& ( LCS_SD != *p_lcs)
|
|
&& ( LCS_SE != *p_lcs)
|
|
&& ( LCS_FA != *p_lcs))
|
|
{
|
|
ERROR("LCM state error. LCS = 0x%x\n", (unsigned int)*p_lcs );
|
|
panic;
|
|
}
|
|
else
|
|
{
|
|
NOTICE("LCM state is %s\n",lcs_name[*p_lcs]);
|
|
}
|
|
}
|
|
|
|
md = (mem_read32(RST_MODEMR0) & RST_MODEMR0_MD5) >> 5U;
|
|
|
|
if (LCS_SD == *p_lcs)
|
|
{
|
|
/* LCS=SD => Normal boot */
|
|
is_verify = NORMAL_BOOT;
|
|
}
|
|
else if ((LCS_SE != *p_lcs) && ( 1U == md))
|
|
{
|
|
/* LCS=CM/DM/FA and MD5=1 => Normal boot */
|
|
is_verify = NORMAL_BOOT;
|
|
}
|
|
else
|
|
{
|
|
/* LCS=SE => Secure boot */
|
|
/* LCS=CM/DM/FA and MD5=0 => Secure boot */
|
|
is_verify = SECURE_BOOT;
|
|
}
|
|
|
|
if (NORMAL_BOOT != is_verify)
|
|
{
|
|
#if (RCAR_LSI == RCAR_S4)
|
|
NOTICE("Secure boot(CA55 Loader)\n");
|
|
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
|
|
#ifdef AARCH64
|
|
NOTICE("Secure boot(CA76 Loader)\n");
|
|
#else
|
|
NOTICE("Secure boot(CR52 Loader)\n");
|
|
#endif
|
|
#endif /* RCAR_LSI == RCAR_S4 */
|
|
}
|
|
else
|
|
{
|
|
#if (RCAR_LSI == RCAR_S4)
|
|
NOTICE("Normal boot(CA55 Loader)\n");
|
|
#elif ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
|
|
#ifdef AARCH64
|
|
NOTICE("Normal boot(CA76 Loader)\n");
|
|
#else
|
|
NOTICE("Normal boot(CR52 Loader)\n");
|
|
#endif
|
|
#endif /* RCAR_LSI == RCAR_S4 */
|
|
}
|
|
|
|
return is_verify;
|
|
|
|
}
|
|
/* End of function judge_bootmode(void) */
|
|
|
|
void secureboot_verify(LOAD_INFO* li, uint32_t start, uint32_t end)
|
|
{
|
|
uint32_t *p_cmac;
|
|
r_icumif_isd_t *p_ISD;
|
|
uint32_t loop;
|
|
uint32_t i;
|
|
volatile uintptr_t p_content_cert;
|
|
volatile uintptr_t p_key_cert;
|
|
|
|
secureboot_memset(ISD_BUFFER, 0U, SIZE_OF_ISD_BUFFER);
|
|
|
|
p_ISD = (r_icumif_isd_t *)ISD_BUFFER;
|
|
|
|
/* Set Load info parameter */
|
|
for (loop = start; loop < end; loop++)
|
|
{
|
|
secureboot_memset(CMAC_BUFFER, 0U, SIZE_OF_CMAC_BUFFER);
|
|
p_cmac = (uint32_t *)CMAC_BUFFER;
|
|
p_ISD->service_id = SERVICE_00_SECURE_BOOT_API;
|
|
p_ISD->ptr.p_callbackfunc = NULL;
|
|
p_ISD->job_id = 0U;
|
|
p_ISD->res_nointerrupt = R_ICUMIF_REQRES_NOINTERRPUT;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.boot_api_id
|
|
= ROM_SECURE_BOOT_VERIFY;
|
|
p_key_cert = li[loop].key_cert_addr;
|
|
p_content_cert = li[loop].cnt_cert_addr;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr1.p_key_cert = (uint32_t*)p_key_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr2.p_content_cert = (uint32_t*)p_content_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr3.p_cmac = p_cmac;
|
|
|
|
/* trigger the service request */
|
|
secureboot_service(p_ISD);
|
|
if(ROMAPI_OK != p_ISD->prm.SECURE_BOOT_API.api_return_value)
|
|
{
|
|
ERROR("SECURE_BOOT_API:Error code = (0x%x).\n",
|
|
(unsigned int)p_ISD->prm.SECURE_BOOT_API.api_return_value);
|
|
panic;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0U; i < CX_CMAC_COPY; i++)
|
|
{
|
|
li[loop].cmac[i] = *(p_cmac++);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
|
|
/* Set Load info parameter */
|
|
/* For RTOS#0 */
|
|
secureboot_memset(CMAC_BUFFER, 0U, CX_CMAC_SIZE);
|
|
p_cmac = (uint32_t *)CMAC_BUFFER;
|
|
p_ISD->service_id = SERVICE_00_SECURE_BOOT_API;
|
|
p_ISD->ptr.p_callbackfunc = NULL;
|
|
p_ISD->job_id = 0U;
|
|
p_ISD->res_nointerrupt = R_ICUMIF_REQRES_NOINTERRPUT;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.boot_api_id
|
|
= ROM_SECURE_BOOT_VERIFY;
|
|
p_key_cert = li[RTOS_ID].key_cert_addr;
|
|
p_content_cert = li[RTOS_ID].cnt_cert_addr;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr1.p_key_cert = (uint32_t*)p_key_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr2.p_content_cert = (uint32_t*)p_content_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr3.p_cmac = p_cmac;
|
|
|
|
/* trigger the service request */
|
|
secureboot_service(p_ISD);
|
|
if(ROMAPI_OK != p_ISD->prm.SECURE_BOOT_API.api_return_value)
|
|
{
|
|
ERROR("SECURE_BOOT_API:Error code = (0x%x).\n",
|
|
(unsigned int)p_ISD->prm.SECURE_BOOT_API.api_return_value);
|
|
panic;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0U; i < CX_CMAC_COPY; i++)
|
|
{
|
|
li[RTOS_ID].cmac[i] = *(p_cmac++);
|
|
}
|
|
}
|
|
|
|
#if (RTOS_LOAD_NUM == RTOS_LOAD_NUM_3)
|
|
/* For RTOS#1,RTOS#2 */
|
|
for (loop = RTOS1_ID; loop <= RTOS2_ID; loop++)
|
|
{
|
|
secureboot_memset(CMAC_BUFFER, 0U, CX_CMAC_SIZE);
|
|
p_cmac = (uint32_t *)CMAC_BUFFER;
|
|
p_ISD->service_id = SERVICE_00_SECURE_BOOT_API;
|
|
p_ISD->ptr.p_callbackfunc = NULL;
|
|
p_ISD->job_id = 0U;
|
|
p_ISD->res_nointerrupt = R_ICUMIF_REQRES_NOINTERRPUT;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.boot_api_id
|
|
= ROM_SECURE_BOOT_VERIFY;
|
|
p_key_cert = li[loop].key_cert_addr;
|
|
p_content_cert = li[loop].cnt_cert_addr;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr1.p_key_cert = (uint32_t*)p_key_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr2.p_content_cert = (uint32_t*)p_content_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_verify.ptr3.p_cmac = p_cmac;
|
|
|
|
/* trigger the service request */
|
|
secureboot_service(p_ISD);
|
|
if(ROMAPI_OK != p_ISD->prm.SECURE_BOOT_API.api_return_value)
|
|
{
|
|
ERROR("SECURE_BOOT_API:Error code = (0x%x).\n",
|
|
(unsigned int)p_ISD->prm.SECURE_BOOT_API.api_return_value);
|
|
panic;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0U; i < CX_CMAC_COPY; i++)
|
|
{
|
|
li[loop].cmac[i] = *(p_cmac++);
|
|
}
|
|
}
|
|
}
|
|
#endif /* RTOS_LOAD_NUM == RTOS_LOAD_NUM_3 */
|
|
#endif /* RCAR_LSI == RCAR_V4H || RCAR_LSI == RCAR_V4M */
|
|
|
|
}
|
|
/* End of function secureboot_verify(void) */
|
|
|
|
int secureboot_image(LOAD_INFO* li, int do_panic)
|
|
{
|
|
uint32_t *p_cmac;
|
|
uint32_t *p_hash;
|
|
r_icumif_isd_t *p_ISD;
|
|
uint32_t i;
|
|
volatile uintptr_t p_content_cert;
|
|
|
|
secureboot_memset(ISD_BUFFER, 0U, SIZE_OF_ISD_BUFFER);
|
|
secureboot_memset(CMAC_BUFFER, 0U, SIZE_OF_CMAC_BUFFER);
|
|
secureboot_memset(HASH_BUFFER, 0U, SIZE_OF_HASH_BUFFER);
|
|
|
|
/* initialize the global icum service header */
|
|
p_ISD = (r_icumif_isd_t *)ISD_BUFFER;
|
|
p_cmac = (uint32_t *)CMAC_BUFFER;
|
|
p_hash = (uint32_t *)HASH_BUFFER;
|
|
|
|
for (i = 0U; i < CX_CMAC_COPY; i++)
|
|
{
|
|
*(p_cmac++) = li->cmac[i];
|
|
}
|
|
|
|
p_ISD->service_id = SERVICE_00_SECURE_BOOT_API;
|
|
p_ISD->ptr.p_callbackfunc = NULL;
|
|
p_ISD->job_id = 0U;
|
|
p_ISD->res_nointerrupt = R_ICUMIF_REQRES_NOINTERRPUT;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.boot_api_id = ROM_SECURE_BOOT_DECRYPT;
|
|
|
|
p_content_cert = li->cnt_cert_addr;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_decrypt.ptr1.p_content_cert = (uint32_t*)p_content_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_decrypt.ptr2.p_cmac = (uint32_t *)CMAC_BUFFER;
|
|
|
|
/* trigger the service request */
|
|
secureboot_service(p_ISD);
|
|
if(( ROMAPI_OK != p_ISD->prm.SECURE_BOOT_API.api_return_value) &&
|
|
(ROM_ERR_IMG_VERIFIER_NO_ENCRYPT_IMG != p_ISD->prm.SECURE_BOOT_API.api_return_value))
|
|
{
|
|
ERROR("SECURE_BOOT_API:Error code = (0x%x).\n",
|
|
(unsigned int)p_ISD->prm.SECURE_BOOT_API.api_return_value);
|
|
if (do_panic)
|
|
panic;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
p_ISD->service_id = SERVICE_00_SECURE_BOOT_API;
|
|
p_ISD->ptr.p_callbackfunc = NULL;
|
|
p_ISD->job_id = 0U;
|
|
p_ISD->res_nointerrupt = R_ICUMIF_REQRES_NOINTERRPUT;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.boot_api_id = ROM_SECURE_BOOT_COMPARE;
|
|
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_compare.ptr1.p_content_cert = (uint32_t*)p_content_cert;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_compare.ptr2.p_hash = p_hash;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_compare.hash_size_in_bytes = SIZE_OF_HASH_BUFFER;
|
|
p_ISD->prm.SECURE_BOOT_API.api.
|
|
boot_compare.ptr3.p_cmac = (uint32_t *)CMAC_BUFFER;
|
|
|
|
/* trigger the service request */
|
|
secureboot_service(p_ISD);
|
|
if(ROMAPI_OK != p_ISD->prm.SECURE_BOOT_API.api_return_value)
|
|
{
|
|
ERROR("SECURE_BOOT_API:Error code = (0x%x).\n",
|
|
(unsigned int)p_ISD->prm.SECURE_BOOT_API.api_return_value);
|
|
if (do_panic)
|
|
panic;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
/* End of function secureboot_image(LOAD_INFO* li) */
|
|
|
|
|
|
static void secureboot_memset(void *buff, uint32_t data, uint32_t cnt)
|
|
{
|
|
uint32_t *tmp = NULL;
|
|
uint32_t loop = cnt / CX_SIZEOF_CNT; /* Copy 4 bytes at a time */
|
|
tmp = (uint32_t *)buff;
|
|
|
|
if (buff == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
while (loop > 0U)
|
|
{
|
|
*tmp = data;
|
|
tmp++;
|
|
loop--;
|
|
}
|
|
}/* End of function secureboot_memset(void *buff, uint32_t data, uint32_t cnt) */
|
|
|
|
static void secureboot_service(r_icumif_isd_t *p_ISD)
|
|
{
|
|
int32_t r_errno;
|
|
|
|
/* trigger the service request */
|
|
r_errno = R_ICUMIF_ServiceRequest(p_ISD);
|
|
if(R_ICUMIF_ER_OK != r_errno)
|
|
{
|
|
ERROR("R_ICUMIF_ServiceRequest:Error code = (0x%x).\n", (unsigned int)r_errno);
|
|
panic;
|
|
}
|
|
|
|
/* wait for response */
|
|
while(true)
|
|
{
|
|
r_errno = R_ICUMIF_IsServiceCompleted(p_ISD);
|
|
if(r_errno != R_ICUMIF_RTN_SERV_RUNNING)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(SERV_OK != p_ISD->service_result)
|
|
{
|
|
ERROR("R_ICUMIF_IsServiceCompleted:Error code = (0x%x).\n", p_ISD->service_result);
|
|
panic;
|
|
}
|
|
|
|
r_errno = R_ICUMIF_ServiceResponse();
|
|
if(R_ICUMIF_ER_OK != r_errno)
|
|
{
|
|
ERROR("R_ICUMIF_ServiceResponse:Error code = (0x%x).\n", (unsigned int)r_errno);
|
|
panic;
|
|
}
|
|
|
|
}
|
|
/* End of function secureboot_service(r_icumif_isd_t *p_ISD) */
|
|
|
|
void final_hash_cmp(void)
|
|
{
|
|
#if ((RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M))
|
|
uint32_t i;
|
|
uint32_t j;
|
|
uint8_t *hash1;
|
|
uint8_t *hash2;
|
|
uintptr_t hash_addr[HASH_CMP_NUM] = {SECURE_FW_HASH_SAVE_ADDR, CR52_IPL_HASH_SAVE_ADDR};
|
|
|
|
for(i = 0U; i < HASH_CMP_NUM; i++)
|
|
{
|
|
/* Hash is placed SystemRAM by ICUMX IPL. */
|
|
hash1 = (uint8_t *)(hash_addr[i]);
|
|
hash2 = (uint8_t *)(hash_addr[i] + HASH_SIZE);
|
|
|
|
for(j = 0U; j < HASH_SIZE; j++)
|
|
{
|
|
/* Compare Hash */
|
|
if(*hash1 != *hash2)
|
|
{
|
|
/* Hash unmatch. */
|
|
ERROR("Final Hash compare error!!\n");
|
|
panic;
|
|
}
|
|
hash1++;
|
|
hash2++;
|
|
}
|
|
}
|
|
#endif /* (RCAR_LSI == RCAR_V4H) || (RCAR_LSI == RCAR_V4M) */
|
|
}
|
|
/* End of function final_hash_cmp(void) */
|
|
|