/*********************************************************************************************************************** * FILE DESCRIPTION * ------------------------------------------------------------------------------------------------------------------*/ /** \file * \brief BM Header module * * -------------------------------------------------------------------------------------------------------------------- * COPYRIGHT * -------------------------------------------------------------------------------------------------------------------- * \par Copyright * \verbatim * Copyright (c) 2024 by Vector Informatik GmbH. All rights reserved. * * This software is copyright protected and proprietary to Vector Informatik GmbH. * Vector Informatik GmbH grants to you only those rights as set out in the license conditions. * All other rights remain with Vector Informatik GmbH. * \endverbatim */ /**********************************************************************************************************************/ /*********************************************************************************************************************** * REVISION HISTORY * -------------------------------------------------------------------------------------------------------------------- * Version Date Author Change Id Description * -------------------------------------------------------------------------------------------------------------------- * 01.00.00 2019-31-01 visrie - Initial release * 01.01.00 2019-02-18 vismvi - No changes * visrie ESCAN00102184 Maximum number of verification entries are not correctly evaluated * 01.02.00 2019-07-22 visrie ESCAN00103790 Support invalid entry address configuration * ESCAN00103791 Support of custom verification * ESCAN00103803 No changes * 02.00.00 2019-12-03 visrie FBL-456 Added support for new FblLibSecBoot interface * 02.00.01 2020-01-15 visrie ESCAN00105368 Added missing encapsulation * 02.01.00 2022-02-25 vistbe FBL-4128 Added/adapted MemMap sections * 02.02.00 2024-08-29 viswmo FBL-9163 Add target-based BmHdrHeader search for updater **********************************************************************************************************************/ #define BM_HDR_SOURCE /*********************************************************************************************************************** * INCLUDES **********************************************************************************************************************/ #include "fbl_inc.h" #include "bm_main.h" #include "fbl_lbt_access.h" #if defined( FBLBM_ENABLE_SECURE_BOOT ) # include "fbl_secboot.h" #endif /*********************************************************************************************************************** * VERSION **********************************************************************************************************************/ #if ( FBLBM_HDR_VERSION != 0x0202u ) || \ ( FBLBM_HDR_RELEASE_VERSION != 0x00u ) # error "Error in bm_hdr.c: Source and Header file are inconsistent!" #endif #if ( FBLBM_HDR_VERSION != _FBLBM_HDR_VERSION ) || ( FBLBM_HDR_RELEASE_VERSION != _FBLBM_HDR_RELEASE_VERSION ) # error "Error in bm_hdr.c: Source and v_ver.h are inconsistent!" #endif /*********************************************************************************************************************** * DEFINES **********************************************************************************************************************/ /*********************************************************************************************************************** * GLOBAL FUNCTIONS **********************************************************************************************************************/ #define FBLBMHDR_START_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * FblBmHdrGetBmHeader **********************************************************************************************************************/ /*! \brief Validate a specific bootmanager header of a logical block * \param[in] targetHandle Target handle (e.g. Bootloader, Application) * \param[in] bmHeaderAddress Location of the BmHeader structure. * \param[out] bmHeader Buffer for the BmHeader * \return Result of operation * FBLBMHDR_CHKHDR_OK when operation succeeded * FBLBMHDR_CHKHDR_READ_FAIL when reading the BmHeader failed * FBLBMHDR_CHKHDR_HEADER_INCONSISTENT when the BmHeader is inconsistent * FBLBMHDR_CHKHDR_WRONG_TARGET when the BmHeader is for another target **********************************************************************************************************************/ tFblBmHdrCheckBmHeaderResult FblBmHdrGetBmHeader(tFblBmHdrTargetHandle targetHandle, tFblAddress bmHeaderAddress, V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader) { tFblBmHdrCheckBmHeaderResult result; result = FBLBMHDR_CHKHDR_OK; if (FblReadProm(bmHeaderAddress, (vuint8 *)bmHeader, sizeof(tFblBmHdrHeader)) != sizeof(tFblBmHdrHeader)) { result = FBLBMHDR_CHKHDR_READ_FAIL; } /* Check for correct target handle */ if (result == FBLBMHDR_CHKHDR_OK) { if (bmHeader->bmTargetHandle != targetHandle) { result = FBLBMHDR_CHKHDR_WRONG_TARGET; } } /* Check for consistency errors */ if (result == FBLBMHDR_CHKHDR_OK) { if (kFblOk != FblBmHdrCheckConsistency(bmHeader)) { result = FBLBMHDR_CHKHDR_HEADER_INCONSISTENT; } } return result; } /* PRQA S 6010 */ /* MD_MSR_STPTH */ /*********************************************************************************************************************** * FblBmHdrCheckConsistency **********************************************************************************************************************/ /*! \brief Checks the consistency of the BM header structure * \param[in] bmHeader: Pointer to the BM Header structure * \return Result of operation **********************************************************************************************************************/ tFblResult FblBmHdrCheckConsistency( const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * pBmHeader ) { tFblResult result; #if defined( FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST ) vuintx i; #endif /* FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST */ /* Initialize variables */ result = kFblOk; /* Check magic value */ if (pBmHeader->bmMagicFlag != FBLBMHDR_MAGIC_FLAG) { result = kFblFailed; } #if defined( FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST ) /* Check number of verification regions */ if (result == kFblOk) { if (pBmHeader->bmVerificationListEntries > FBLBMHDR_NUM_OF_VERIFICATION_ENTRIES) { result = kFblFailed; } } /* Check if a verification region contains the entry address */ if ( (result == kFblOk) && (pBmHeader->bmEntryAddress != FBLBMHDR_ENTRY_ADDRESS_INVALID)) { /* Change result to failed, it will be set back to OK if a valid region was found */ result = kFblFailed; for (i = 0u; i < pBmHeader->bmVerificationListEntries; i++) { if ( (pBmHeader->bmEntryAddress >= pBmHeader->bmVerificationList[i].address) && (pBmHeader->bmEntryAddress < (pBmHeader->bmVerificationList[i].address + pBmHeader->bmVerificationList[i].length))) { /* Entry address is in a verification range */ result = kFblOk; break; } } } #endif /* FBLBMHDR_ENABLE_HEADER_VERIFICATION_LIST */ return result; } #if defined( FBLBM_CALLOUT_IS_VALIDBLOCK ) /*********************************************************************************************************************** * FblBmHdrFindValidHeader **********************************************************************************************************************/ /*! \brief Find a valid bootmanager header structure for the given target * \param[in] targetHandle Target handle (e.g. Bootloader, Application) * \param[in,out] pBlockInfo Pointer to a structure which holds a pointer to the BM header and the corresponding * logical block. * \return Result of operation * FBLBMHDR_CHKHDR_OK A valid BmHeader is found * FBLBMHDR_CHKHDR_NOT_FOUND No BmHeader found * FBLBMHDR_CHKHDR_BLOCK_INVALID Logical block is not valid * see FblBmHdrCheckBmHeader for further return values. * see FblBmHdrVerifyBmHeader for further return values. **********************************************************************************************************************/ tFblBmHdrCheckBmHeaderResult FblBmHdrFindValidHeader(tFblBmHdrTargetHandle targetHandle, V_MEMRAM1 tFblBmBlockInfo V_MEMRAM2 V_MEMRAM3 * pBlockInfo) { tFblBmHdrCheckBmHeaderResult result; tFblLbtBlockFilter blockFilter; /* Initialize variables */ result = FBLBMHDR_CHKHDR_NOT_FOUND; /* Iterate over all mandatory blocks */ FblLbtBlockFilterInit(&blockFilter); pBlockInfo->logicalBlock = FblLbtBlockFirst(&blockFilter); while (FblLbtBlockDone() == FALSE) { if (kFblOk == FBLBM_CALLOUT_IS_VALIDBLOCK(targetHandle, &pBlockInfo->logicalBlock)) { result = FblBmHdrGetBmHeader(targetHandle, pBlockInfo->logicalBlock.bmHeaderAddress, &pBlockInfo->bmHeader); } else { result = FBLBMHDR_CHKHDR_BLOCK_INVALID; } if (result == FBLBMHDR_CHKHDR_OK) { /* Leave loop after first hit */ break; } /* Prepare next cycle */ pBlockInfo->logicalBlock = FblLbtBlockNext(); } return result; } #endif /* FBLBM_CALLOUT_IS_VALIDBLOCK */ #define FBLBMHDR_STOP_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * END OF FILE: BM_HDR.C **********************************************************************************************************************/