<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/bootloader/bootloader.C $                                 */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2022                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/**
 * @file bootloader.C
 *
 * @brief Bootloader main() function and various helper functions
 */

#define __BOOT_LOADER_C

#include <stdint.h>
#include <bootloader/bootloader.H>
#include <bootloader/bootloader_trace.H>
#include <bootloader/hbblreasoncodes.H>
#include <bootloader/bl_pnorAccess.H>
#include <bootloader/bootloaderif.H>
#include <bootloader/bl_console.H>
#include <bootloader/bl_xscom.H>

#include <lpc_const.H>
#include <pnor_utils.H>
#include <arch/pvrformat.H>
#include <arch/ppc.H>

#include <ecc.H>

#include <stdlib.h>
#include <util/align.H>
#include <string.h>
#include <limits.h>
#include <math.h>

#include <securerom/ROM.H>
#include <secureboot/secure_reasoncodes.H>
#include <secureboot/settings_common.H>
#include <p10_sbe_hb_structures.H>

#include <pnor/pnorif.H>
#include <kernel/memstate.H>

#include <p10_sbe_spi_cmd.H>
#include <bl_tpm_spidd.H>

using namespace MEMMAP;

extern char bootloader_end_address;

// XSCOM/LPC BAR constants
const uint64_t XSCOM_BAR_MASK = 0xFF000003FFFFFFFFULL;
const uint64_t LPC_BAR_MASK = 0xFF000000FFFFFFFFULL;


// Offset into the secure header of the hash and size of protected payload
const uint16_t CONTENT_HASH_OFFSET = 1085;
const uint16_t CONTENT_PROTECTED_SIZE_OFFSET = CONTENT_HASH_OFFSET - 8;

namespace Bootloader{

    /**
     * @brief Set Secureboot Config Data structure so it is accessible via
     *        Hostboot code
     *
     * @param[in] i_hbbSrc  Void pointer to effective address of HBB image
     *                      inlcuding the header. Must not be NULL
     *
     * @return N/A
     */
    void setSecureData(const void * i_pHbbSrc)
    {
        // Create BlToHbData

        // Read SBE HB shared data.
        const BootloaderConfigData_t* l_blConfigData =
            reinterpret_cast<BootloaderConfigData_t *>(SBE_HB_COMM_ADDR);

        // Set Secure Settings
        // Ensure SBE to Bootloader structure has the SAB member
        //   and other Secure Settings
        g_blData->blToHbData.secureAccessBit =
            l_blConfigData->secureSettings.secureAccessBit;
        g_blData->blToHbData.securityOverride =
            l_blConfigData->secureSettings.securityOverride;
        g_blData->blToHbData.allowAttrOverrides =
            l_blConfigData->secureSettings.allowAttrOverrides;
        g_blData->blToHbData.secBackdoorBit =
            l_blConfigData->secureSettings.secBackdoorBit;

        // Find secure ROM addr
        // Get starting address of ROM size and code which is the next 8 byte
        // aligned address after the bootloader end.
        // [hbbl][pad:8:if-applicable][securerom-size:8][securerom]
        const void * l_pBootloaderEnd = &bootloader_end_address;
        uint64_t l_bootloaderSize = 0;
        memcpy (&l_bootloaderSize, l_pBootloaderEnd, sizeof(l_bootloaderSize));
        const uint8_t* l_pRomStart = reinterpret_cast<uint8_t *>(
                                        getHRMOR() + ALIGN_8(l_bootloaderSize));

        // Set Rom Size
        memcpy (&g_blData->blToHbData.secureRomSize,
                l_pRomStart,
                sizeof(g_blData->blToHbData.secureRomSize));
        l_pRomStart += sizeof(g_blData->blToHbData.secureRomSize);

        // Get Secure ROM info
        const auto l_pSecRomInfo = reinterpret_cast<const SecureRomInfo*>(
                                                                   l_pRomStart);

        // Translate SBE to BL version into BL to HB version
        switch(l_blConfigData->version)
        {
            // Add cases as additional versions are created
            case SB_SETTING:
            default:
                g_blData->blToHbData.version = BLTOHB_TPM_FFDC;
                break;
        }

        /* lpcBAR and xscomBAR already copied in main() */

        // Only set rest of BlToHbData if SecureROM is valid
        if ( secureRomInfoValid(l_pSecRomInfo) )
        {
            // Store valid check local to bootloader, as another validation
            // is required in code outside the bootloader.
            g_blData->secureRomValid = true;

            g_blData->blToHbData.eyeCatch = BLTOHB_EYECATCHER;
            g_blData->blToHbData.branchtableOffset =
                                               l_pSecRomInfo->branchtableOffset;
            g_blData->blToHbData.secureRom = l_pRomStart;

            // Set data size of HW key hash
            g_blData->blToHbData.hwKeysHashSize = SHA512_DIGEST_LENGTH;

            // Get HW Keys' Hash Ptr
            g_blData->blToHbData.hwKeysHashPtr = &l_blConfigData->sbSettings.hwKeyHash[0];

            // Get Minimum Secure Version
            g_blData->blToHbData.min_secure_version = l_blConfigData->sbSettings.msv;

            // Get Measurement Seeprom Version
            g_blData->blToHbData.measurement_seeprom_version =
                l_blConfigData->mSeepromVersion;

            // Set HBB header and size
            g_blData->blToHbData.hbbHeader = i_pHbbSrc;
            g_blData->blToHbData.hbbHeaderSize = PAGE_SIZE;

            // Set Bootloader preceived size of structure
            g_blData->blToHbData.sizeOfStructure = sizeof(BlToHbData);
        }
    }

    void setKeyAddrMapData(const void * i_pHbbSrc)
    {
        // Read SBE HB shared data.
        const auto l_blConfigData = reinterpret_cast<BootloaderConfigData_t *>(
                                                              SBE_HB_COMM_ADDR);
        // Set copy keyaddr stash data
        memcpy(&g_blData->blToHbData.keyAddrStashData,
               &l_blConfigData->pair,
               (l_blConfigData->numKeyAddrPair * sizeof(keyAddrPair_t)));

        g_blData->blToHbData.numKeyAddrPair = l_blConfigData->numKeyAddrPair;
    }

    void copyBlToHbtoHbLocation()
    {
        // Place BlToHb into proper location for HB to find
        memcpy(reinterpret_cast<void *>(BLTOHB_COMM_DATA_ADDR_LATEST |
                                        IGNORE_HRMOR_MASK),
                &g_blData->blToHbData,
                sizeof(BlToHbData));
    }

    /**
     *  @brief Verify container's component ID against a reference
     *     component ID. Up to 8 ASCII characters, not including NULL, will be
     *     compared (thus, it is critical that all components are unique with
     *     respect to the first 8 bytes).
     *
     *  @param[in] i_pHeader Void pointer to start of the container's secure
     *      header.  Must not be nullptr.
     *  @param[in] i_pComponentId Reference component ID to compare to.  Must
     *      not be nullptr.
     */
    void verifyComponentId(
        const void* const i_pHeader,
        const char* const i_pComponentId)
    {

        const auto* const pHwPrefix =
            reinterpret_cast<const ROM_prefix_header_raw* const>(
                  reinterpret_cast<const uint8_t* const>(i_pHeader)
                + offsetof(ROM_container_raw,prefix));
        const auto swKeyCount = pHwPrefix->sw_key_count;
        const auto ecidCount = pHwPrefix->ecid_count;

        const char* const pCompIdInContainer =
              reinterpret_cast<const char* const>(i_pHeader)
            + offsetof(ROM_container_raw,prefix)
            + offsetof(ROM_prefix_header_raw,ecid)
            + ecidCount*ECID_SIZE
            + offsetof(ROM_prefix_data_raw,sw_pkey_p)
            + swKeyCount*sizeof(ecc_key_t)
            + offsetof(ROM_sw_header_raw,component_id);

        if(strncmp(pCompIdInContainer,
                   i_pComponentId,
                   sizeof(ROM_sw_header_raw::component_id)) != 0)
        {
            char pTruncatedComponentId[
                  sizeof(ROM_sw_header_raw::component_id)
                + sizeof(uint8_t)]={0};
            strncpy(pTruncatedComponentId,
                    i_pComponentId,
                    sizeof(ROM_sw_header_raw::component_id));

            BOOTLOADER_TRACE(BTLDR_TRC_COMP_ID_VERIFY_FAILED);

            // Read SBE HB shared data
            const auto pBlConfigData = reinterpret_cast<
                BootloaderConfigData_t *>(SBE_HB_COMM_ADDR);

            /*@
             * @errortype
             * @moduleid         Bootloader::MOD_BOOTLOADER_VERIFY_COMP_ID
             * @reasoncode       SECUREBOOT::RC_ROM_VERIFY
             * @userdata1[0:15]  TI_WITH_SRC
             * @userdata1[16:31] TI_BOOTLOADER
             * @userdata1[32:63] Failing address = 0
             * @userdata2[0:31]  First 4 bytes of observed component ID
             * @userdata2[32:63] Last 4 bytes of observed component ID
             * @errorInfo[0:15]  SBE boot side
             * @errorInfo[16:31] Unused
             * @devdesc          Container component ID verification failed.
             * @custdesc         Platform security violation detected
             */
            bl_terminate(
                MOD_BOOTLOADER_VERIFY_COMP_ID,
                SECUREBOOT::RC_ROM_VERIFY,
                *reinterpret_cast<const uint32_t*>(
                   pCompIdInContainer),
                *reinterpret_cast<const uint32_t*>(
                   pCompIdInContainer+sizeof(uint32_t)),
                true,
                0,
                TWO_UINT16_TO_UINT32(
                    pBlConfigData->sbeBootSide,0));
        }
        else
        {
            BOOTLOADER_TRACE(BTLDR_TRC_COMP_ID_VERIFY_SUCCESS);
        }
    }

    /**
     * @brief Verify Container against system hash keys
     *
     * @param[in] i_pContainer  Void pointer to effective address
     *                          of container
     *
     * @return N/A
     */
    void verifyContainer(const void * i_pContainer)
    {
        BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_START);

        uint64_t l_rc = 0;

        // Check if Secure Access Bit is set
        if (!g_blData->blToHbData.secureAccessBit)
        {
            BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_SAB_UNSET);

            // In non-secure mode the following will happen:
            // 1) Assume that the Container starts with a secureboot header
            // 2) Measure the container from after the secureboot header until the end
            //    - Use the "protected size" value in the secure header for the measurement
            //    - This ensures that we are measuring (and eventually extending to the TPM)
            //      EXACTLY what is being loaded on the system
            // 3) Put the hash value from that measurement into the secureboot header
            //    - The call_rom_SHA512() function below accomplishes tasks 2 and 3 at the same time

            // Set startAddr to SHA512_HASH_FUNCTION_OFFSET ROM_verify() function at an offset of Secure ROM
            uint64_t l_rom_SHA512_startAddr =
                reinterpret_cast<const uint64_t>(g_blData->blToHbData.secureRom)
                + g_blData->blToHbData.branchtableOffset
                + SHA512_HASH_FUNCTION_OFFSET;

            // In non-secure mode must skip past the secure header at the start of the container
            uint8_t* l_pContainer = reinterpret_cast<uint8_t*>(const_cast<void*>(i_pContainer));
            uint8_t* l_blob_addr = l_pContainer + PAGE_SIZE;

            // While the protected size section in the secure header is 8 bytes/uint64_t,
            // the hash function takes in a uint32_t
            uint64_t l_protectedSize_u64 = 0;
            memcpy(&l_protectedSize_u64,
                   l_pContainer + CONTENT_PROTECTED_SIZE_OFFSET,
                   sizeof(l_protectedSize_u64));
            uint32_t l_protectedSize = l_protectedSize_u64;

            // Location of hash of the "protected payload" into the secure header
            // - This location is used for extending the hash to the TPM
            uint64_t l_hash = reinterpret_cast<uint64_t>(i_pContainer) +
                                  CONTENT_HASH_OFFSET;

            call_rom_SHA512(reinterpret_cast<void*>(l_rom_SHA512_startAddr),
                            l_blob_addr,
                            l_protectedSize,
                            reinterpret_cast<SHA512_t*>(l_hash));

        }
        // Terminate if a valid securerom is not present
        else if ( !g_blData->secureRomValid )
        {
            BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_INVALID_SECROM);
            /*@
             * @errortype
             * @moduleid     Bootloader::MOD_BOOTLOADER_VERIFY
             * @reasoncode   SECUREBOOT::RC_SECROM_INVALID
             * @userdata1[0:15]   TI_WITH_SRC
             * @userdata1[16:31]  TI_BOOTLOADER
             * @userdata1[32:63]  Failing address = 0
             * @devdesc      Valid securerom not present
             * @custdesc     Security failure occurred while running processor
             *               boot code.
             */
            bl_terminate(Bootloader::MOD_BOOTLOADER_VERIFY,
                         SECUREBOOT::RC_SECROM_INVALID);
        }
        else
        {
            bl_console::putString("Validating boot firmware\r\n");
            // Set startAddr to ROM_verify() function at an offset of Secure ROM
            uint64_t l_rom_verify_startAddr =
                reinterpret_cast<const uint64_t>(g_blData->blToHbData.secureRom)
                + g_blData->blToHbData.branchtableOffset
                + ROM_VERIFY_FUNCTION_OFFSET;

            // Declare local input struct
            ROM_hw_params l_hw_parms;

            // Clear/zero-out the struct since we want 0 ('zero') values for
            // struct elements my_ecid, entry_point and log
            uint8_t *p_hw_parms = reinterpret_cast<uint8_t *>(&l_hw_parms);
            for(uint8_t i = 0; i < sizeof(ROM_hw_params); p_hw_parms[i++] = 0){}

            // Use current hw hash key
            memcpy (&l_hw_parms.hw_key_hash, g_blData->blToHbData.hwKeysHashPtr,
                    sizeof(SHA512_t));

            // Use current minimum FW secure version
            l_hw_parms.log = g_blData->blToHbData.min_secure_version;

            const auto l_container = reinterpret_cast<const ROM_container_raw*>
                                                                 (i_pContainer);

            l_rc = call_rom_verify(reinterpret_cast<void*>
                                   (l_rom_verify_startAddr),
                                   l_container,
                                   &l_hw_parms);
            if (l_rc != 0)
            {
                // Get first 4 bytes of Container that failed verification
                uint32_t l_beginContainer = 0;<commit_msg>Add Common Fail Messages to HBBL Console Output<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/bootloader/bootloader.C $                                 */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2022                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/**
 * @file bootloader.C
 *
 * @brief Bootloader main() function and various helper functions
 */

#define __BOOT_LOADER_C

#include <stdint.h>
#include <bootloader/bootloader.H>
#include <bootloader/bootloader_trace.H>
#include <bootloader/hbblreasoncodes.H>
#include <bootloader/bl_pnorAccess.H>
#include <bootloader/bootloaderif.H>
#include <bootloader/bl_console.H>
#include <bootloader/bl_xscom.H>

#include <lpc_const.H>
#include <pnor_utils.H>
#include <arch/pvrformat.H>
#include <arch/ppc.H>

#include <ecc.H>

#include <stdlib.h>
#include <util/align.H>
#include <string.h>
#include <limits.h>
#include <math.h>

#include <securerom/ROM.H>
#include <secureboot/secure_reasoncodes.H>
#include <secureboot/settings_common.H>
#include <p10_sbe_hb_structures.H>

#include <pnor/pnorif.H>
#include <kernel/memstate.H>

#include <p10_sbe_spi_cmd.H>
#include <bl_tpm_spidd.H>

using namespace MEMMAP;

extern char bootloader_end_address;

// XSCOM/LPC BAR constants
const uint64_t XSCOM_BAR_MASK = 0xFF000003FFFFFFFFULL;
const uint64_t LPC_BAR_MASK = 0xFF000000FFFFFFFFULL;


// Offset into the secure header of the hash and size of protected payload
const uint16_t CONTENT_HASH_OFFSET = 1085;
const uint16_t CONTENT_PROTECTED_SIZE_OFFSET = CONTENT_HASH_OFFSET - 8;

namespace Bootloader{

    /**
     * @brief Set Secureboot Config Data structure so it is accessible via
     *        Hostboot code
     *
     * @param[in] i_hbbSrc  Void pointer to effective address of HBB image
     *                      inlcuding the header. Must not be NULL
     *
     * @return N/A
     */
    void setSecureData(const void * i_pHbbSrc)
    {
        // Create BlToHbData

        // Read SBE HB shared data.
        const BootloaderConfigData_t* l_blConfigData =
            reinterpret_cast<BootloaderConfigData_t *>(SBE_HB_COMM_ADDR);

        // Set Secure Settings
        // Ensure SBE to Bootloader structure has the SAB member
        //   and other Secure Settings
        g_blData->blToHbData.secureAccessBit =
            l_blConfigData->secureSettings.secureAccessBit;
        g_blData->blToHbData.securityOverride =
            l_blConfigData->secureSettings.securityOverride;
        g_blData->blToHbData.allowAttrOverrides =
            l_blConfigData->secureSettings.allowAttrOverrides;
        g_blData->blToHbData.secBackdoorBit =
            l_blConfigData->secureSettings.secBackdoorBit;

        // Find secure ROM addr
        // Get starting address of ROM size and code which is the next 8 byte
        // aligned address after the bootloader end.
        // [hbbl][pad:8:if-applicable][securerom-size:8][securerom]
        const void * l_pBootloaderEnd = &bootloader_end_address;
        uint64_t l_bootloaderSize = 0;
        memcpy (&l_bootloaderSize, l_pBootloaderEnd, sizeof(l_bootloaderSize));
        const uint8_t* l_pRomStart = reinterpret_cast<uint8_t *>(
                                        getHRMOR() + ALIGN_8(l_bootloaderSize));

        // Set Rom Size
        memcpy (&g_blData->blToHbData.secureRomSize,
                l_pRomStart,
                sizeof(g_blData->blToHbData.secureRomSize));
        l_pRomStart += sizeof(g_blData->blToHbData.secureRomSize);

        // Get Secure ROM info
        const auto l_pSecRomInfo = reinterpret_cast<const SecureRomInfo*>(
                                                                   l_pRomStart);

        // Translate SBE to BL version into BL to HB version
        switch(l_blConfigData->version)
        {
            // Add cases as additional versions are created
            case SB_SETTING:
            default:
                g_blData->blToHbData.version = BLTOHB_TPM_FFDC;
                break;
        }

        /* lpcBAR and xscomBAR already copied in main() */

        // Only set rest of BlToHbData if SecureROM is valid
        if ( secureRomInfoValid(l_pSecRomInfo) )
        {
            // Store valid check local to bootloader, as another validation
            // is required in code outside the bootloader.
            g_blData->secureRomValid = true;

            g_blData->blToHbData.eyeCatch = BLTOHB_EYECATCHER;
            g_blData->blToHbData.branchtableOffset =
                                               l_pSecRomInfo->branchtableOffset;
            g_blData->blToHbData.secureRom = l_pRomStart;

            // Set data size of HW key hash
            g_blData->blToHbData.hwKeysHashSize = SHA512_DIGEST_LENGTH;

            // Get HW Keys' Hash Ptr
            g_blData->blToHbData.hwKeysHashPtr = &l_blConfigData->sbSettings.hwKeyHash[0];

            // Get Minimum Secure Version
            g_blData->blToHbData.min_secure_version = l_blConfigData->sbSettings.msv;

            // Get Measurement Seeprom Version
            g_blData->blToHbData.measurement_seeprom_version =
                l_blConfigData->mSeepromVersion;

            // Set HBB header and size
            g_blData->blToHbData.hbbHeader = i_pHbbSrc;
            g_blData->blToHbData.hbbHeaderSize = PAGE_SIZE;

            // Set Bootloader preceived size of structure
            g_blData->blToHbData.sizeOfStructure = sizeof(BlToHbData);
        }
    }

    void setKeyAddrMapData(const void * i_pHbbSrc)
    {
        // Read SBE HB shared data.
        const auto l_blConfigData = reinterpret_cast<BootloaderConfigData_t *>(
                                                              SBE_HB_COMM_ADDR);
        // Set copy keyaddr stash data
        memcpy(&g_blData->blToHbData.keyAddrStashData,
               &l_blConfigData->pair,
               (l_blConfigData->numKeyAddrPair * sizeof(keyAddrPair_t)));

        g_blData->blToHbData.numKeyAddrPair = l_blConfigData->numKeyAddrPair;
    }

    void copyBlToHbtoHbLocation()
    {
        // Place BlToHb into proper location for HB to find
        memcpy(reinterpret_cast<void *>(BLTOHB_COMM_DATA_ADDR_LATEST |
                                        IGNORE_HRMOR_MASK),
                &g_blData->blToHbData,
                sizeof(BlToHbData));
    }

    /**
     *  @brief Verify container's component ID against a reference
     *     component ID. Up to 8 ASCII characters, not including NULL, will be
     *     compared (thus, it is critical that all components are unique with
     *     respect to the first 8 bytes).
     *
     *  @param[in] i_pHeader Void pointer to start of the container's secure
     *      header.  Must not be nullptr.
     *  @param[in] i_pComponentId Reference component ID to compare to.  Must
     *      not be nullptr.
     */
    void verifyComponentId(
        const void* const i_pHeader,
        const char* const i_pComponentId)
    {

        const auto* const pHwPrefix =
            reinterpret_cast<const ROM_prefix_header_raw* const>(
                  reinterpret_cast<const uint8_t* const>(i_pHeader)
                + offsetof(ROM_container_raw,prefix));
        const auto swKeyCount = pHwPrefix->sw_key_count;
        const auto ecidCount = pHwPrefix->ecid_count;

        const char* const pCompIdInContainer =
              reinterpret_cast<const char* const>(i_pHeader)
            + offsetof(ROM_container_raw,prefix)
            + offsetof(ROM_prefix_header_raw,ecid)
            + ecidCount*ECID_SIZE
            + offsetof(ROM_prefix_data_raw,sw_pkey_p)
            + swKeyCount*sizeof(ecc_key_t)
            + offsetof(ROM_sw_header_raw,component_id);

        if(strncmp(pCompIdInContainer,
                   i_pComponentId,
                   sizeof(ROM_sw_header_raw::component_id)) != 0)
        {
            char pTruncatedComponentId[
                  sizeof(ROM_sw_header_raw::component_id)
                + sizeof(uint8_t)]={0};
            strncpy(pTruncatedComponentId,
                    i_pComponentId,
                    sizeof(ROM_sw_header_raw::component_id));

            BOOTLOADER_TRACE(BTLDR_TRC_COMP_ID_VERIFY_FAILED);

            // Read SBE HB shared data
            const auto pBlConfigData = reinterpret_cast<
                BootloaderConfigData_t *>(SBE_HB_COMM_ADDR);

            /*@
             * @errortype
             * @moduleid         Bootloader::MOD_BOOTLOADER_VERIFY_COMP_ID
             * @reasoncode       SECUREBOOT::RC_ROM_VERIFY
             * @userdata1[0:15]  TI_WITH_SRC
             * @userdata1[16:31] TI_BOOTLOADER
             * @userdata1[32:63] Failing address = 0
             * @userdata2[0:31]  First 4 bytes of observed component ID
             * @userdata2[32:63] Last 4 bytes of observed component ID
             * @errorInfo[0:15]  SBE boot side
             * @errorInfo[16:31] Unused
             * @devdesc          Container component ID verification failed.
             * @custdesc         Platform security violation detected
             */
            bl_terminate(
                MOD_BOOTLOADER_VERIFY_COMP_ID,
                SECUREBOOT::RC_ROM_VERIFY,
                *reinterpret_cast<const uint32_t*>(
                   pCompIdInContainer),
                *reinterpret_cast<const uint32_t*>(
                   pCompIdInContainer+sizeof(uint32_t)),
                true,
                0,
                TWO_UINT16_TO_UINT32(
                    pBlConfigData->sbeBootSide,0));
        }
        else
        {
            BOOTLOADER_TRACE(BTLDR_TRC_COMP_ID_VERIFY_SUCCESS);
        }
    }

    /**
     * @brief Verify Container against system hash keys
     *
     * @param[in] i_pContainer  Void pointer to effective address
     *                          of container
     *
     * @return N/A
     */
    void verifyContainer(const void * i_pContainer)
    {
        BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_START);

        uint64_t l_rc = 0;

        // Used in multiple places below: Set startAddr to SHA512_HASH_FUNCTION_OFFSET
        // call_rom_SHA512() function at an offset of Secure ROM
        const uint64_t l_rom_SHA512_startAddr =
            reinterpret_cast<const uint64_t>(g_blData->blToHbData.secureRom)
                + g_blData->blToHbData.branchtableOffset
                + SHA512_HASH_FUNCTION_OFFSET;

        // Check if Secure Access Bit is set
        if (!g_blData->blToHbData.secureAccessBit)
        {
            BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_SAB_UNSET);

            // In non-secure mode the following will happen:
            // 1) Assume that the Container starts with a secureboot header
            // 2) Measure the container from after the secureboot header until the end
            //    - Use the "protected size" value in the secure header for the measurement
            //    - This ensures that we are measuring (and eventually extending to the TPM)
            //      EXACTLY what is being loaded on the system
            // 3) Put the hash value from that measurement into the secureboot header
            //    - The call_rom_SHA512() function below accomplishes tasks 2 and 3 at the same time

            // In non-secure mode must skip past the secure header at the start of the container
            uint8_t* l_pContainer = reinterpret_cast<uint8_t*>(const_cast<void*>(i_pContainer));
            uint8_t* l_blob_addr = l_pContainer + PAGE_SIZE;

            // While the protected size section in the secure header is 8 bytes/uint64_t,
            // the hash function takes in a uint32_t
            uint64_t l_protectedSize_u64 = 0;
            memcpy(&l_protectedSize_u64,
                   l_pContainer + CONTENT_PROTECTED_SIZE_OFFSET,
                   sizeof(l_protectedSize_u64));
            uint32_t l_protectedSize = l_protectedSize_u64;

            // Location of hash of the "protected payload" into the secure header
            // - This location is used for extending the hash to the TPM
            uint64_t l_hash = reinterpret_cast<uint64_t>(i_pContainer) +
                                  CONTENT_HASH_OFFSET;

            call_rom_SHA512(reinterpret_cast<void*>(l_rom_SHA512_startAddr),
                            l_blob_addr,
                            l_protectedSize,
                            reinterpret_cast<SHA512_t*>(l_hash));

        }
        // Terminate if a valid securerom is not present
        else if ( !g_blData->secureRomValid )
        {
            BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_INVALID_SECROM);
            /*@
             * @errortype
             * @moduleid     Bootloader::MOD_BOOTLOADER_VERIFY
             * @reasoncode   SECUREBOOT::RC_SECROM_INVALID
             * @userdata1[0:15]   TI_WITH_SRC
             * @userdata1[16:31]  TI_BOOTLOADER
             * @userdata1[32:63]  Failing address = 0
             * @devdesc      Valid securerom not present
             * @custdesc     Security failure occurred while running processor
             *               boot code.
             */
            bl_terminate(Bootloader::MOD_BOOTLOADER_VERIFY,
                         SECUREBOOT::RC_SECROM_INVALID);
        }
        else
        {
            bl_console::putString("Validating boot firmware\r\n");
            // Set startAddr to ROM_verify() function at an offset of Secure ROM
            uint64_t l_rom_verify_startAddr =
                reinterpret_cast<const uint64_t>(g_blData->blToHbData.secureRom)
                + g_blData->blToHbData.branchtableOffset
                + ROM_VERIFY_FUNCTION_OFFSET;

            // Declare local input struct
            ROM_hw_params l_hw_parms;

            // Clear/zero-out the struct since we want 0 ('zero') values for
            // struct elements my_ecid, entry_point and log
            uint8_t *p_hw_parms = reinterpret_cast<uint8_t *>(&l_hw_parms);
            for(uint8_t i = 0; i < sizeof(ROM_hw_params); p_hw_parms[i++] = 0){}

            // Use current system hw hash key
            memcpy (&l_hw_parms.hw_key_hash, g_blData->blToHbData.hwKeysHashPtr,
                    sizeof(SHA512_t));

            // Use current system minimum FW secure version
            l_hw_parms.log = g_blData->blToHbData.min_secure_version;

            const auto l_container = reinterpret_cast<const ROM_container_raw*>
                                                                 (i_pContainer);

            l_rc = call_rom_verify(reinterpret_cast<void*>
                                   (l_rom_verify_startAddr),
                                   l_container,
                                   &l_hw_parms);

            if (l_rc != 0)
            {
                // Look for two most common fails
                const uint64_t l_hw_key_hash_test_fail_rc    = ERROR_EVENT
                                                               | ROM_VERIFY
                                                               | HW_KEY_HASH_TEST;
                const uint64_t l_secure_version_test_fail_rc = ERROR_EVENT
                                                               | ROM_VERIFY
                                                               | SECURE_VERSION_TEST;

                if ((l_hw_parms.log == l_hw_key_hash_test_fail_rc) ||
                    (l_hw_parms.log == l_secure_version_test_fail_rc))
                {

                    // Gather info to add console messages for common fails
                    const uint32_t l_imprint_hash = 0x40d487ff; // Hard-coded, publicly-known value

                    uint32_t l_system_hash = 0;
                    memcpy(&l_system_hash,
                           g_blData->blToHbData.hwKeysHashPtr,
                           sizeof(l_system_hash));
                    uint8_t  l_system_min_version = g_blData->blToHbData.min_secure_version;
                    uint32_t l_container_hash = 0;
                    uint8_t  l_container_min_version = 0;

                    // Get Secure Version from the container
                    // - get sw_key_count and ecid_count
                    const auto* const pHwPrefix =
                        reinterpret_cast<const ROM_prefix_header_raw* const>(
                            reinterpret_cast<const uint8_t* const>(i_pContainer)
                            + offsetof(ROM_container_raw,prefix));
                    const auto swKeyCount = pHwPrefix->sw_key_count;
                    const auto ecidCount = pHwPrefix->ecid_count;

                    // - get pointer to Secure Version in the container
                    const char* const pFwSecureVersionInContainer =
                          reinterpret_cast<const char* const>(i_pContainer)
                            + offsetof(ROM_container_raw,prefix)
                            + offsetof(ROM_prefix_header_raw,ecid)
                            + ecidCount*ECID_SIZE
                            + offsetof(ROM_prefix_data_raw,sw_pkey_p)
                            + swKeyCount*sizeof(ecc_key_t)
                            + offsetof(ROM_sw_header_raw,fw_secure_version);
                    // - copy secure version from the container to a local variable
                    memcpy(&l_container_min_version,
                           pFwSecureVersionInContainer,
                           sizeof(l_container_min_version));

                    // Setup and call hash function on public HW Keys in the container
                    // - Get pointer to public HW Keys in the container
                    const char* const l_pHwPKeyA =
                        reinterpret_cast<const char* const>(i_pContainer)
                        + offsetof(ROM_container_raw,hw_pkey_a);

                    // - get total HW Keys Size and create a variable to hold the hash
                    size_t l_totalHwKeysSize = HW_KEY_COUNT*sizeof(ecc_key_t);
                    SHA512_t l_pContainerHash;
                    // - hash HW Keys
                    call_rom_SHA512(reinterpret_cast<void*>(l_rom_SHA512_startAddr),
                                    reinterpret_cast<const sha2_byte*>(l_pHwPKeyA),
                                    l_totalHwKeysSize,
                                    reinterpret_cast<SHA512_t*>(&l_pContainerHash));
                    // - copy just the first 4 bytes to a local variable
                    memcpy(&l_container_hash, &l_pContainerHash, sizeof(l_container_hash));

                    if (l_rc == l_hw_key_hash_test_fail_rc)
                    {
                        bl_console::putString("\rFAILED HW Keys' Hash Check\r\n");
                    }
                    else
                    {
                        bl_console::putString("\rFAILED Minimum Secure Version Check\r\n");
                    }
                    bl_console::putString("\rHashes: Sys=0x");
                    bl_console::displayHex(reinterpret_cast<unsigned char*>(&l_system_hash),
                                           sizeof(l_system_hash));
                    bl_console::putString("\tContainer=0x");
                    bl_console::displayHex(reinterpret_cast<unsigned char*>(&l_container_hash),
                                           sizeof(l_container_hash));
                    bl_console::putString("\t(imprint hash=0x");
                    bl_console::displayHex(reinterpret_cast<const unsigned char*>(&l_imprint_hash),
                                           sizeof(l_imprint_hash));
                    bl_console::putString(")\r\n");

                    bl_console::putString("\rSecure Versions: Sys=0x");
                    bl_console::displayHex(reinterpret_cast<unsigned char*>(&l_system_min_version),
                                           sizeof(l_system_min_version));
                    bl_console::putString("\tContainer=0x");
                    bl_console::displayHex(reinterpret_cast<unsigned char*>
                                               (&l_container_min_version),
                                           sizeof(l_container_min_version));
                    bl_console::putString("\r\n");
                }

                // Prepare To Terminate The System:
                // Get first 4 bytes of Container that failed verification
                uint32_t l_beginContainer = 0;
{'fraction_non_alphanumeric': 0.07202868584290836, 'fraction_numerical': 0.011516214306278954, 'mean_word_length': 1.6101926492690257, 'pattern_counts': {'":': 0, '<': 111, '<?xml version=': 0, '>': 203, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 117, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7220020', 'n_tokens_mistral': 10904, 'n_tokens_neox': 10157, 'n_words': 2326}