/*********************************************************************************************************************** * 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 **********************************************************************************************************************/