/************************************************************************** * * Copyright (c) 2021 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file Integrity.c * * @author (last) Quang Nguyen * @date (last) 11-May-2021 * * @author (last) Quang Nguyen * @date (last) 11-May-2021 * ***************************************************************************/ #include #include "Integrity.h" #include "Utilities.h" /** * @addtogroup Integrity * @{ */ // ********** private definitions ********** #define CRC_TABLE_STARTING_ADDR 0x20 ///< The starting address of CRC table for firmware image. #define MAX_CRC_CALC_DATA_SIZE 0x8000 ///< The maximum size of data for each CRC calculation. // ********** private data ********** static U32 currentRecord; ///< Current CRC table record to check. static U32 currentProcessedSize; ///< Current data size processed for CRC calculation. static U32 crcCalculated; ///< The calculated CRC value. static SELF_TEST_STATUS_T integrityTestStatus; ///< Current firmware integrity test status. static U32 calculateCrc( U32 const crcValue, U08 * dataPtr, U32 size, U32 crcAlgoId ); /*********************************************************************//** * @brief * The initIntegrity function initializes the Integrity module. * @details Inputs: none * @details Outputs: Integrity module initialized * @return none *************************************************************************/ void initIntegrity( void ) { currentRecord = 0; currentProcessedSize = 0; crcCalculated = 0; integrityTestStatus = SELF_TEST_STATUS_IN_PROGRESS; } /*********************************************************************//** * @brief * The execIntegrityTest function executes the integrity check for firmware image. * @details Inputs: firmware image CRC table * @details Outputs: none * @return firmware image integrity self-test status *************************************************************************/ SELF_TEST_STATUS_T execIntegrityTest( void ) { CRC_TABLE const * const crcTablePtr = (CRC_TABLE *)CRC_TABLE_STARTING_ADDR; CRC_RECORD const * const currentRecordPtr = &crcTablePtr->recs[ currentRecord ]; BOOL integrityStatus = TRUE; U32 remainingSize = 0; if ( currentRecord < crcTablePtr->num_recs ) { remainingSize = currentRecordPtr->size - currentProcessedSize; if ( remainingSize > MAX_CRC_CALC_DATA_SIZE ) { crcCalculated = calculateCrc( crcCalculated, (U08 *)( currentRecordPtr->addr + currentProcessedSize ), MAX_CRC_CALC_DATA_SIZE, currentRecordPtr->crc_alg_ID ); currentProcessedSize += MAX_CRC_CALC_DATA_SIZE; } else { crcCalculated = calculateCrc( crcCalculated, (U08 *)( currentRecordPtr->addr + currentProcessedSize ), remainingSize, currentRecordPtr->crc_alg_ID ); integrityStatus &= ( ( (U32)currentRecordPtr->crc_value == crcCalculated ) ? TRUE : FALSE ); crcCalculated = 0; currentProcessedSize = 0; currentRecord++; } } if ( TRUE != integrityStatus ) { integrityTestStatus = SELF_TEST_STATUS_FAILED; activateAlarmNoData( ALARM_ID_HD_INTEGRITY_POST_TEST_FAILED ); } else if ( currentRecord == crcTablePtr->num_recs ) { integrityTestStatus = SELF_TEST_STATUS_PASSED; } return integrityTestStatus; } /*********************************************************************//** * @brief * The calculateCrc function computes the CRC on the given memory section * and CRC algorithm. * @details Inputs: none * @details Outputs: none * @param crcValue crc initial value * @param dataPtr pointer to data record for CRC calculation * @param size data size to calculate crc * @param crcAlgoId CRC algorithm id number * @return calculated CRC value *************************************************************************/ static U32 calculateCrc( U32 const crcValue, U08 * dataPtr, U32 size, U32 crcAlgoId ) { U32 crcCalc = 0; switch ( crcAlgoId ) { case CRC32_C: crcCalc = crc32( crcValue, dataPtr, size ); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CRC_ALGO, crcAlgoId ) break; } return crcCalc; } /**@}*/