/***********************************************************************************************************************
 *  FILE DESCRIPTION
 *  ------------------------------------------------------------------------------------------------------------------*/
/** \file
 *  \brief         SecureBoot implementation
 *
 *  --------------------------------------------------------------------------------------------------------------------
 *  COPYRIGHT
 *  --------------------------------------------------------------------------------------------------------------------
 *  \par Copyright
 *  \verbatim
 *  Copyright (c) 2025 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   2020-01-07  visrie  FBL-524          Initial release
 *  01.00.01   2020-04-27  visrie  FBL-1773         No changes
 *  02.00.00   2020-05-19  vistbe  FBL-1016         Support EcuM_Init() mechanism
 *  02.01.00   2021-01-19  visrie  FBL-2648         Added support of new SecureBoot verify variant
 *                                 FBL-2641         Updated to new API version
 *  02.02.00   2021-09-03  visjdn  FBL-3352         No changes
 *  02.03.00   2023-06-21  vistbe  FBL-4814         Add support for OTA
 *  02.03.01   2024-05-16  viswmo  ESCAN00117059    Signature failure is not reported
 *  02.04.00   2024-11-18  vismix  FBL-9654         Optimize startup times for secure boot
 *  02.05.00   2025-01-24  vikatya PIO-1340         SecureBoot for selected blocks
 *  02.06.00   2025-02-19  visrie  FBL-10209        Support total length for confirmation mode
 **********************************************************************************************************************/

#define FBL_SECBOOT_SOURCE

/***********************************************************************************************************************
 *  INCLUDES
 **********************************************************************************************************************/

#include "fbl_inc.h"
#include "Std_Types.h"
#include "Csm.h"
#include "bm_types.h"
#include "bm_hdr.h"
#include "fbl_secboot.h"

#if defined( FBLSB_ENABLE_COPY_FLASH_DRIVER )
# include "FlashRom.h"
#endif /* FBLSB_ENABLE_COPY_FLASH_DRIVER */

/***********************************************************************************************************************
 *  VERSION
 **********************************************************************************************************************/

#if ( FBLLIB_SECBOOT_VHSM_VERSION != 0x0206u ) || \
    ( FBLLIB_SECBOOT_VHSM_RELEASE_VERSION != 0x00u )
# error "Error in FBL_SECBOOT.C: Source and Header file are inconsistent!"
#endif

#if ( FBLLIB_SECBOOT_VHSM_VERSION != _FBLLIB_SECBOOT_VHSM_VERSION ) || \
    ( FBLLIB_SECBOOT_VHSM_RELEASE_VERSION != _FBLLIB_SECBOOT_VHSM_RELEASE_VERSION )
# error "Error in FBL_SECBOOT.C: Source and v_ver.h are inconsistent!"
#endif

/***********************************************************************************************************************
 *  DEFINES
 **********************************************************************************************************************/

/** Watchdog triggered every n-th cycle (has to power of two) */
#if !defined( FBLSB_WATCHDOG_CYCLE_COUNT )
# define FBLSB_WATCHDOG_CYCLE_COUNT    0x20u
#endif
/** Trigger watchdog every n-th cycle */
#define FBLSB_TRIGGER_WATCHDOG(cycle)                             \
{                                                                 \
   if (((cycle) & (FBLSB_WATCHDOG_CYCLE_COUNT - 1u)) == 0x00u)    \
   {                                                              \
      (void)FblLookForWatchdog();                                 \
   }                                                              \
}

#define FBLSB_VHSM_AUTHENTICATION_HEADER_HEADER                         20u /* Magic Pattern (16) + Revision (4) */
#define FBLSB_VHSM_AUTHENTICATION_HEADER_GROUPID                        4u  /* GroupId */
#define FBLSB_VHSM_AUTHENTICATION_HEADER_NO_SEGMENTS                    2u  /* Nr of Segments */
#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_BASE                    (FBLSB_VHSM_AUTHENTICATION_HEADER_GROUPID + FBLSB_VHSM_AUTHENTICATION_HEADER_NO_SEGMENTS)
#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENT                 42u /* Address (4) + Length (4) + Mode (2) + Hash (32) */
#define FBLSB_VHSM_AUTHENTICATION_HEADER_SIGNATURE_LENGTH               4u  /* Length field containing the actual length of the signature */
#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENTS(noOfSegments)  \
   ((noOfSegments) * FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENT)
#define FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH(noOfSegments)           \
   (FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_BASE + FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH_SEGMENTS(noOfSegments))

/***********************************************************************************************************************
 *  TYPEDEFS
 **********************************************************************************************************************/

/***********************************************************************************************************************
 *  GLOBAL DATA
 **********************************************************************************************************************/

/***********************************************************************************************************************
 *  LOCAL DATA
 **********************************************************************************************************************/
#define FBLSB_START_SEC_VAR
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */

V_MEMRAM0 static V_MEMRAM1 tFblSbExtErrCode V_MEMRAM2 sbExtErrCode;

#define FBLSB_STOP_SEC_VAR
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
/***********************************************************************************************************************
 *  LOCAL FUNCTION PROTOTYPES
 **********************************************************************************************************************/
#define FBLSB_START_SEC_CODE
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */

#if defined( FBLSB_ENABLE_GENERATE_CMAC )
static tFblLength FblSb_GetAuthenticationHeaderLength(const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * dataPtr);
static tFblResult FblSb_UpdateCommonMac(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader, vuint32 macId);
#endif /* FBLSB_ENABLE_GENERATE_CMAC */

/***********************************************************************************************************************
 *  EXTERNAL DATA
 **********************************************************************************************************************/

/***********************************************************************************************************************
 *  LOCAL FUNCTIONS
 **********************************************************************************************************************/

#if defined( FBLSB_ENABLE_GENERATE_CMAC )
/***********************************************************************************************************************
 *  FblSb_GetAuthenticationHeaderLength
**********************************************************************************************************************/
/*! \brief      Calculates the length of the vHsm authentication header
 *  \param[in]  dataPtr  Pointer to the groupId of the vHsm authentication header
 *  \return     Length of the authentication header
 **********************************************************************************************************************/
static tFblLength FblSb_GetAuthenticationHeaderLength(const V_MEMRAM1 vuint8 V_MEMRAM2 V_MEMRAM3 * dataPtr)
{
   tFblLength authHeaderLength;
   vuint32 noOfSegments;

   noOfSegments = FblMemGetInteger(FBLSB_VHSM_AUTHENTICATION_HEADER_NO_SEGMENTS, &dataPtr[FBLSB_VHSM_AUTHENTICATION_HEADER_GROUPID]);
   authHeaderLength = FBLSB_VHSM_AUTHENTICATION_HEADER_LENGTH(noOfSegments);

   return authHeaderLength;
}

/***********************************************************************************************************************
 *  FblSb_UpdateCommonMac
 **********************************************************************************************************************/
/*! \brief      Generate and write the common MACs
 *  \param[in]  bmHeader  Pointer to the bmHdrHeader structure
 *  \param[in]  macId     MAC operation identifier
 *  \return     Result of operation
 *                   kFblOk when operation succeeded
 *                   kFblFailed otherwise
 **********************************************************************************************************************/
/* PRQA S 3673, 6010, 6030, 6080 1 */ /* MD_MSR_Rule8.13, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */
static tFblResult FblSb_UpdateCommonMac(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader, vuint32 macId)
{
   tFblResult result = kFblOk;
   Crypto_VerifyResultType verifyResult = CRYPTO_E_VER_NOT_OK;
   uint32 jobId = 0u;
   const uint8 * dataPtr;
   uint32 dataLength = 0u;
   uint32 signatureAddress = 0u;
   uint32 signatureLength = 0u;

   /* Check if mac operation is configured. */
   if (macId != FBLBMHDR_MAC_OP_REF_NOT_USED)
   {
      /* Check if the SecureBootGroup can be updated */
      if (macId < FBLSB_NUM_OF_MAC_OPERATIONS)
      {
         /* Check if SecureBootUpdate is actually required */
         if ((FblSb_GetVerificationMethodOfMacOperation(macId) == FBLSB_VERIFICATIONMETHOD_INTERNAL)
# if defined( FBL_ENABLE_OTA )
          && (vOtaM_IsOpenedPartitionOfRoleActive() == E_OK)
# endif /* FBL_ENABLE_OTA */
            )
         {
            jobId = FblSb_GetCsmJobIdOfMacUpdate();
            dataPtr = (const uint8 *)bmHeader->bmAuthenticationHeaderAddress;  /* PRQA S 0306 */ /* MD_FblLibSecBoot_0306 */
            dataLength = FblSb_GetAuthenticationHeaderLength(dataPtr);
            result = ApplFblSbGetSignatureInfo(bmHeader, macId, &signatureAddress, &signatureLength);

            assertFblGen((result == kFblOk), kFblSysAssertParameterOutOfRange);

            if (result == kFblOk)
            {
               /* PRQA S 0306 2 */ /* MD_FblLibSecBoot_0306 */
               if (E_OK == Csm_SignatureVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, dataPtr, dataLength,
                  (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))signatureAddress, signatureLength, &verifyResult))
               {
                  if (verifyResult != CRYPTO_E_VER_OK)
                  {
                     sbExtErrCode = FBLSB_EXT_ERR_CODE_SIGNATURE;
                     result = kFblFailed;
                  }
               }
               else
               {
                  result = kFblFailed;
               }
            }
         }
         else if (FblSb_IsConfirmationModeOfMacOperation(macId))
         {
            boolean inactivePartition = FALSE;

            jobId = FblSb_GetCsmJobIdOfMacConfirmationMode();
            dataPtr = (const uint8 *)bmHeader->bmAuthenticationHeaderAddress;  /* PRQA S 0306 */ /* MD_FblLibSecBoot_0306 */
            dataLength = FBLSB_VHSM_AUTHENTICATION_HEADER_HEADER;
            dataLength += FblSb_GetAuthenticationHeaderLength(&dataPtr[FBLSB_VHSM_AUTHENTICATION_HEADER_HEADER]);
            signatureLength = FblMemGetInteger(FBLSB_VHSM_AUTHENTICATION_HEADER_SIGNATURE_LENGTH, &dataPtr[dataLength]); /* Extract actual signature length */
            dataLength += FBLSB_VHSM_AUTHENTICATION_HEADER_SIGNATURE_LENGTH;
            dataLength += signatureLength;

# if defined( FBL_ENABLE_OTA )
            if (vOtaM_IsOpenedPartitionOfRoleInactive() == E_OK)
            {
               inactivePartition = TRUE;
            }
# endif /* FBL_ENABLE_OTA */

            if (E_OK == Csm_SignatureVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, dataPtr, dataLength,
               (P2CONST(uint8, AUTOMATIC, CSM_APPL_VAR))&inactivePartition, sizeof(inactivePartition), &verifyResult))
            {
               if (verifyResult != CRYPTO_E_VER_OK)
               {
                  sbExtErrCode = FBLSB_EXT_ERR_CODE_SIGNATURE;
                  result = kFblFailed;
               }
            }
            else
            {
               result = kFblFailed;
            }
         }
         else
         {
            result = kFblFailed;
         }
      }
      else
      {
         /* This block has no SecureBootGroup and therefore can not be updated */
         result = kFblFailed;
      }

      if (   (result != kFblOk)
          && (sbExtErrCode == FBLSB_EXT_ERR_CODE_NONE) )
      {
         sbExtErrCode = FBLSB_EXT_ERR_CODE_GENERAL;
      }
   }

   return result;
}
#endif /* FBLSB_ENABLE_GENERATE_CMAC */

/***********************************************************************************************************************
 *  GLOBAL FUNCTIONS
 **********************************************************************************************************************/

#if defined( FBLSB_ENABLE_COPY_FLASH_DRIVER )
/***********************************************************************************************************************
 *  FblUpdCopyFlashDriver
 ***********************************************************************************************************************/
/*! \brief        Copies the flashdriver from the ROM table into flashCode buffer
 ***********************************************************************************************************************/
void FblSb_CopyFlashDriver( void )
{
   vuint16 index;

   /* flashCode buffer location must match the flashdriver start address */
# if defined( FLASH_DRIVER_RELOCATABLE )
# else
   if ( (flashCode == (IO_U8 *)FLASHDRV_BLOCK0_ADDRESS) )
# endif /* FLASH_DRIVER_RELOCATABLE */
   {
      /* Copy all flash driver code from ROM into the flashCode buffer */
      for (index = 0u; index < FLASHDRV_BLOCK0_LENGTH; index++)
      {
         FBLSB_TRIGGER_WATCHDOG(index);
         flashCode[index] = FLASHDRV_DECRYPTDATA(flashDrvBlk0[index]);
      }
   }
}
#endif /* FBLSB_ENABLE_COPY_FLASH_DRIVER */

/***********************************************************************************************************************
 *  FblSb_Init
 ***********************************************************************************************************************/
/*! \brief        Initializes the SecureBoot module
 *  \details      Initializes the complete crypto stack
 ***********************************************************************************************************************/
void FblSb_Init(void)
{
   /* Crypto stack is initialized via EcuM_Init */

   sbExtErrCode = FBLSB_EXT_ERR_CODE_NONE;
}

/***********************************************************************************************************************
 *  FblSb_VerifyFblLbt
 **********************************************************************************************************************/
/*! \brief      Verifies the BmHdrHeader and the LogicalBlockTable of the bootloader
 *  \param[in]  fblHeader      Pointer to the FBL Header
 *  \return     Result of operation
 *                   kFblOk when operation succeeded
 *                   kFblFailed otherwise or when the feature is disabled
 **********************************************************************************************************************/
tFblResult FblSb_VerifyFblLbt(const V_MEMRAM1 tFblHeader V_MEMRAM2 V_MEMRAM3 * fblHeader)
{
   tFblResult result = kFblFailed;
#if defined( FBLBM_ENABLE_SECURE_BOOT )
# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION )
   Crypto_VerifyResultType verifyResult = CRYPTO_E_VER_NOT_OK;
   uint32 jobId = 0u;
   uint32 groupId = 0u;
# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */
#endif /* FBLBM_ENABLE_SECURE_BOOT */

#if defined( V_ENABLE_USE_DUMMY_STATEMENT )
   /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */
   (void)fblHeader;
#endif

#if defined( FBLBM_ENABLE_SECURE_BOOT )
# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION )
   jobId = FblSb_GetCsmJobIdOfMacVerify();
   groupId = FblSb_GetGroupIdOfMacOperation(FBLSB_SECOND_AUTH_MAC_OPERATION_ID);

   /* Verify the FBL-Header and the LBT */
   if (Csm_MacVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, (uint8 *)&groupId, sizeof(groupId), NULL_PTR, 0u, &verifyResult) == E_OK)
   {
      result = kFblOk;
   }

   if ((result == kFblOk) && (verifyResult != CRYPTO_E_VER_OK))
   {
      result = kFblFailed;
   }
# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */
#endif /* FBLBM_ENABLE_SECURE_BOOT */

   return result;
}

/***********************************************************************************************************************
 *  FblSb_VerifyHeader
 **********************************************************************************************************************/
/*! \brief      Verifies the header
 *  \param[in]  bmHdrHeader      Pointer to the FblBmHdrHeader structure
 *  \return     Result of operation
 *                   kFblFailed always (unsupported feature)
 **********************************************************************************************************************/
tFblResult FblSb_VerifyHeader(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader)
{
#if defined( V_ENABLE_USE_DUMMY_STATEMENT )
   /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */
   (void)bmHdrHeader;
#endif

   return kFblFailed;
}

/***********************************************************************************************************************
 *  FblSb_VerifyHeaderRom
 **********************************************************************************************************************/
/*! \brief      Verifies the MAC of the BmHdrHeader structure at a specific address
 *  \param[in]  bmHeaderAddress  Address of the bmHdrHeader structure
 *  \param[in]  bmHdrHeader      Pointer to the FblBmHdrHeader structure
 *  \return     kFblFailed always (unsupported feature)
 **********************************************************************************************************************/
tFblResult FblSb_VerifyHeaderRom(tFblAddress bmHeaderAddress, const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader)
{
#if defined( V_ENABLE_USE_DUMMY_STATEMENT )
   /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */
   (void)bmHeaderAddress;
   (void)bmHdrHeader;
#endif

   return kFblFailed;
}

/***********************************************************************************************************************
 *  FblSb_UpdateInitialSegments
 **********************************************************************************************************************/
/*! \brief      Updates the SecureBootSegments based on the initial values.
 *  \return     Result of operation
 *                   kFblOk when operation succeeded
 *                   kFblFailed otherwise
 **********************************************************************************************************************/
tFblResult FblSb_UpdateInitialSegments(void)
{
   tFblResult result = kFblOk;
   Crypto_VerifyResultType verifyResult;
   uint32 jobId;
   vuint32 macOperationIdx;
   uint32 groupId;

   /* Iterrate over the configuration */
   for (macOperationIdx = 0u; ((macOperationIdx < FBLSB_NUM_OF_MAC_OPERATIONS) && (result == kFblOk)); macOperationIdx++)
   {
      jobId = FblSb_GetCsmJobIdOfMacVerifyForceSequential();

      if (FblSb_IsVerifyForceSequentialOfMacOperation(macOperationIdx))
      {
         result = kFblFailed;
         verifyResult = CRYPTO_E_VER_NOT_OK;
         groupId = FblSb_GetGroupIdOfMacOperation(macOperationIdx);
         if (Csm_MacVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, (uint8 *)&groupId, sizeof(groupId), NULL_PTR, 0u, &verifyResult) == E_OK)
         {
            if (verifyResult == CRYPTO_E_VER_OK)
            {
               result = kFblOk;
            }
         }
      }
   }

   return result;
}

/***********************************************************************************************************************
 *  FblSb_VerifySegments
 **********************************************************************************************************************/
/*! \brief      Verifies the segments
 *  \details    Triggers a verification of the configured SecureBootGroup.
 *  \param[in]  bmHdrHeader      Pointer to the FblBmHdrHeader structure
 *  \return     Result of operation
 *                   kFblOk when operation succeeded
 *                   kFblFailed otherwise
 **********************************************************************************************************************/
tFblResult FblSb_VerifySegments(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHdrHeader)
{
   tFblResult result = kFblFailed;
   Crypto_VerifyResultType verifyResult = CRYPTO_E_VER_NOT_OK;
   uint32 macId = FblBmHdr_GetFblSbMacId(bmHdrHeader->bmTargetHandle);
   uint32 jobId;
   uint32 groupId;

   /* Check if mac operation is configured. */
   if (macId != FBLBMHDR_MAC_OP_REF_NOT_USED)
   {
      if (macId < FBLSB_NUM_OF_MAC_OPERATIONS)
      {
         jobId = FblSb_GetCsmJobIdOfMacVerify();
         groupId = FblSb_GetGroupIdOfMacOperation(macId);
         if (E_OK == Csm_MacVerify(jobId, CRYPTO_OPERATIONMODE_SINGLECALL, (uint8 *)&groupId, sizeof(groupId), NULL_PTR, 0u, &verifyResult))
         {
            result = kFblOk;
         }
      }

      if(   (result == kFblOk)
         && (verifyResult != CRYPTO_E_VER_OK))
      {
         result = kFblFailed;
      }
   }
   else
   {
      result = kFblOk;
   }

   return result;
}

#if defined( FBLSB_ENABLE_GENERATE_CMAC )
/***********************************************************************************************************************
 *  FblSb_UpdateFblMac
 **********************************************************************************************************************/
/*! \brief      Generate and write the necessary MACs for the FBL
 *  \param[in]  fblHeader      Pointer to the FBL Header
 *  \return     Result of operation
 *                   kFblOk when operation succeeded
 *                   kFblFailed otherwise
 **********************************************************************************************************************/
tFblResult FblSb_UpdateFblMac(V_MEMROM1 tFblHeader V_MEMROM2 V_MEMROM3 * fblHeader)
{
   tFblResult result = kFblFailed;
   tFblBmHdrHeader bmHeader = { 0u };
   vuint32 macId = 0u;

   /* Clear any previous errors */
   sbExtErrCode = FBLSB_EXT_ERR_CODE_NONE;

   /* Read BM Header */
   /* PRQA S 0306 1 */ /* MD_FblLibSecBoot_0306 */
   if (FblReadProm((tFblAddress)fblHeader->bmHeader, (vuint8 *)&bmHeader, sizeof(bmHeader)) == sizeof(bmHeader))
   {
      result = FblBmHdrCheckConsistency(&bmHeader);
   }
   else
   {
      sbExtErrCode = FBLSB_EXT_ERR_CODE_MEMORY;
   }

   if (result == kFblOk)
   {
      /* Update the MAC for the first validation structure, used for all FBL segments */
      macId = FblBmHdr_GetFblSbMacId(bmHeader.bmTargetHandle);
      result = FblSb_UpdateCommonMac(&bmHeader, macId);
   }

#if defined( FBLBM_ENABLE_SECURE_BOOT )
# if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION )
   if (result == kFblOk)
   {
      /* Now update the MAC of the second validation structure */
      bmHeader.bmAuthenticationHeaderAddress = FBLSB_SECOND_AUTH_HEADER_ADDRESS;
      result = FblSb_UpdateCommonMac(&bmHeader, FBLSB_SECOND_AUTH_MAC_OPERATION_ID);
   }
# endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */
#endif /* FBLBM_ENABLE_SECURE_BOOT */

   return result;
}

/***********************************************************************************************************************
 *  FblSb_UpdateBlockMac
 **********************************************************************************************************************/
/*! \brief      Generate and write the necessary MACs for a logical block
 *  \param[in]  blockDescriptor  Pointer to the logical block
 *  \param[in]  segmentList      Pointer to the segments
 *  \return     Result of operation
 *                   kFblOk when operation succeeded
 *                   kFblFailed otherwise
 **********************************************************************************************************************/
/* PRQA S 3673 2 */ /* MD_MSR_Rule8.13 */
tFblResult FblSb_UpdateBlockMac(const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * blockDescriptor,
   V_MEMRAM1 FL_SegmentListType V_MEMRAM2 V_MEMRAM3 * segmentList)
{
   tFblResult result = kFblFailed;
   tFblBmHdrHeader bmHeader = { 0u };
   vuint32 macId = 0u;

#if defined( V_ENABLE_USE_DUMMY_STATEMENT )
   /* Parameters not used: avoid compiler warning */ /* PRQA S 3112 2 */ /* MD_MSR_DummyStmt */
   (void)segmentList;
#endif

   /* Clear any previous errors */
   sbExtErrCode = FBLSB_EXT_ERR_CODE_NONE;

   /* Read BM Header */
   if (FblReadProm(blockDescriptor->bmHeaderAddress, (vuint8 *)&bmHeader, sizeof(bmHeader)) == sizeof(bmHeader))
   {
      result = FblBmHdrCheckConsistency(&bmHeader);
   }
   else
   {
      sbExtErrCode = FBLSB_EXT_ERR_CODE_MEMORY;
   }

   if (result == kFblOk)
   {
      macId = FblBmHdr_GetFblSbMacId(bmHeader.bmTargetHandle);
      result = FblSb_UpdateCommonMac(&bmHeader, macId);
   }

   return result;
}
#endif /* FBLSB_ENABLE_GENERATE_CMAC */

/***********************************************************************************************************************
 *  FblSb_GetExtendedErrorCode
 **********************************************************************************************************************/
/*! \brief        Returns an extended error information from previous call to FblSb_UpdateBlockMac/FblSb_UpdateFblMac
 *  \return       Extended error code
 **********************************************************************************************************************/
tFblSbExtErrCode FblSb_GetExtendedErrorCode(void)
{
   return sbExtErrCode;
}

#define FBLSB_STOP_SEC_CODE
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */

/***********************************************************************************************************************
 *  MISRA
 **********************************************************************************************************************/

/* Justification for module-specific MISRA deviations:

   MD_FblLibSecBoot_0306:
      Reason:     Address conversion between integer values and pointers is required to allow for hardware independent
                  configuration and address range checks.
      Risk:       The size of integer required to hold the result of a pointer cast is implementation-defined.
      Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware
                  specific basis. The correctness of the respective implementation is verified by runtime tests.

*/

/***********************************************************************************************************************
 *  END OF FILE: FBL_SECBOOT.C
 **********************************************************************************************************************/
