diff options
-rw-r--r-- | src/bootloader/bootloader.C | 114 | ||||
-rw-r--r-- | src/include/bootloader/bootloaderif.H | 78 |
2 files changed, 152 insertions, 40 deletions
diff --git a/src/bootloader/bootloader.C b/src/bootloader/bootloader.C index 4d764cd04..3091e018c 100644 --- a/src/bootloader/bootloader.C +++ b/src/bootloader/bootloader.C @@ -30,6 +30,7 @@ #include <bootloader/bootloader_trace.H> #include <bootloader/hbblreasoncodes.H> #include <bootloader/bl_pnorAccess.H> +#include <bootloader/bootloaderif.H> #include <lpc_const.H> #include <pnor_utils.H> @@ -58,15 +59,71 @@ namespace Bootloader{ */ uint8_t *g_blScratchSpace = NULL; + // Global Object that will be stored where the SBE HB structure indicates + BlToHbData g_blToHbData; + + // Global bool indicating if the secureROM is valid. Toggles verification. + bool g_secureRomValid = false; + /** - * @brief Retrieve the internal hardware hash key from secure ROM object. - * @param[out] o_hash Reference to the sha2_hash_t array to copy the - * hash to. + * @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 setHwKeyHash(sha2_hash_t o_hash) + void setSecureData(const void * i_pHbbSrc) { - memcpy(o_hash, reinterpret_cast<void *>(HW_KEYS_HASH_ADDR), - sizeof(sha2_hash_t)); + // 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)); + + // Create BlToHbData + // Set Rom Size + memcpy (&g_blToHbData.secureRomSize, + l_pRomStart, + sizeof(g_blToHbData.secureRomSize)); + l_pRomStart += sizeof(g_blToHbData.secureRomSize); + + // Get Secure ROM info + const auto l_pSecRomInfo = reinterpret_cast<const SecureRomInfo*>( + l_pRomStart); + + // 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_secureRomValid = true; + + g_blToHbData.eyeCatch = BLTOHB_EYECATCHER; + g_blToHbData.version = BLTOHB_INIT; + g_blToHbData.branchtableOffset = l_pSecRomInfo->branchtableOffset; + g_blToHbData.secureRom = l_pRomStart; + + // Set HW key hash pointer (20K - 64 bytes) and size + g_blToHbData.hwKeysHash = reinterpret_cast<const void *> + (HW_KEYS_HASH_ADDR); + g_blToHbData.hwKeysHashSize = SHA512_DIGEST_LENGTH; + + // Set HBB header and size + g_blToHbData.hbbHeader = i_pHbbSrc; + g_blToHbData.hbbHeaderSize = PAGE_SIZE; + } + + // Place structure into proper location for HB to find + memcpy(reinterpret_cast<void *>(BLTOHB_COMM_DATA_ADDR | + IGNORE_HRMOR_MASK), + &g_blToHbData, + sizeof(BlToHbData)); } /** @@ -92,38 +149,16 @@ namespace Bootloader{ * * @return N/A */ - void verifyContainer(const void * i_pContainer, - const sha2_hash_t* i_hwKeyHash) + void verifyContainer(const void * i_pContainer) { #ifdef CONFIG_SECUREBOOT BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_START); uint64_t l_rc = 0; - // @TODO RTC:166848 Move find/get secure rom logic out of ROM verify - // 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)); - uint64_t l_rom_startAddr = getHRMOR() + ALIGN_8(l_bootloaderSize); - // Get Rom Size - // @TODO RTC:166848 Store size so hb can use - uint64_t l_secureRomSize = 0; - memcpy (&l_secureRomSize, reinterpret_cast<void*>(l_rom_startAddr), - sizeof(l_secureRomSize)); - l_rom_startAddr += sizeof(l_secureRomSize); - - // Beginning of SecureROM has a info structure - // Get Secure ROM info - const auto l_pSecRomInfo = reinterpret_cast<SecureRomInfo*>( - l_rom_startAddr); - // # @TODO RTC:170136 terminate in this case // Ensure SecureRom is actually present - if ( !secureRomInfoValid(l_pSecRomInfo) ) + if ( !g_secureRomValid ) { BOOTLOADER_TRACE(BTLDR_TRC_MAIN_VERIFY_NO_EYECATCH); } @@ -136,9 +171,10 @@ namespace Bootloader{ else { // Set startAddr to ROM_verify() function at an offset of Secure ROM - uint64_t l_rom_verify_startAddr = l_rom_startAddr - + l_pSecRomInfo->branchtableOffset - + ROM_VERIFY_FUNCTION_OFFSET; + uint64_t l_rom_verify_startAddr = + reinterpret_cast<const uint64_t>(g_blToHbData.secureRom) + + g_blToHbData.branchtableOffset + + ROM_VERIFY_FUNCTION_OFFSET; // Declare local input struct ROM_hw_params l_hw_parms; @@ -147,9 +183,9 @@ namespace Bootloader{ // struct elements my_ecid, entry_point and log memset(&l_hw_parms, 0, sizeof(ROM_hw_params)); - // Use current hw hash key - memcpy (&l_hw_parms.hw_key_hash, i_hwKeyHash, sizeof(sha2_hash_t)); + memcpy (&l_hw_parms.hw_key_hash, g_blToHbData.hwKeysHash, + sizeof(sha2_hash_t)); const auto l_container = reinterpret_cast<const ROM_container_raw*> (i_pContainer); @@ -197,7 +233,6 @@ namespace Bootloader{ bootloader_trace_index = 0; BOOTLOADER_TRACE(BTLDR_TRC_MAIN_START); - // Set variables needed for getting location of HB base code // @TODO RTC:138268 Support multiple sides of PNOR in bootloader //pnorEnd is the end of flash, which is base of lpc, plus @@ -270,12 +305,11 @@ namespace Bootloader{ reinterpret_cast<uint64_t*>(HBB_RUNNING_ADDR | IGNORE_HRMOR_MASK); - // Get HW keys hash - sha2_hash_t l_hwKeyHash{0}; - setHwKeyHash(l_hwKeyHash); + // Get Secure Data from SBE HBBL communication area + setSecureData(l_src_addr); // ROM verification of HBB image - verifyContainer(l_src_addr, &l_hwKeyHash); + verifyContainer(l_src_addr); // Increment past secure header if (isSecureSection(PNOR::HB_BASE_CODE)) diff --git a/src/include/bootloader/bootloaderif.H b/src/include/bootloader/bootloaderif.H index beffe7c0f..47b011542 100644 --- a/src/include/bootloader/bootloaderif.H +++ b/src/include/bootloader/bootloaderif.H @@ -25,6 +25,10 @@ #ifndef __BOOT_LOADERIF_H #define __BOOT_LOADERIF_H +#include <arch/ppc.H> +#include <securerom/ROM.H> + +namespace Bootloader{ // Max size of HBBL without ECC. Must match PNOR layout for eyeCatch HBBL // Must be aligned CACHELINE_SIZE of 128 bytes #define MAX_HBBL_SIZE (20 * KILOBYTE) @@ -32,4 +36,78 @@ // Size of exception vector reserved space at start of the HBBL section #define HBBL_EXCEPTION_VECTOR_SIZE (12 * KILOBYTE) +// The Bootloader to Hostboot communication area exists after the working HBB +#ifdef BOOTLOADER +#define BLTOHB_COMM_DATA_ADDR (getHRMOR() - ( 2*MEGABYTE) + 512*KILOBYTE) +#else +#define BLTOHB_COMM_DATA_ADDR (getHRMOR() + 512*KILOBYTE) +#endif + +// Expected BlToHbData eye catch +const uint64_t BLTOHB_EYECATCHER = 0x23626C746F686200; // #BLTOHB\0 + +// Used for version checking as the BlToHbData structure changes +enum BlToHbDataVersion +{ + // [release:4][version:4] + BLTOHB_INIT = 0x0000000900000001 +}; + + +/** @struct BlToHbData + * @brief Shared data between bootloader and Hostboot. + * + * A shared structure of information that the bootloader has that hostboot + * does not. The Bootloader fills in this structure and places in the agreed + * on location with hostboot. Hostboot's kernel reads this structure out and + * saves it off before the pagemgr clears the cachelines. + * + */ +struct BlToHbData +{ + BlToHbData() : eyeCatch(0), version(BLTOHB_INIT), + branchtableOffset(0), secureRom(nullptr), + secureRomSize(0), hwKeysHash(nullptr), + hwKeysHashSize(0), hbbHeader(nullptr), + hbbHeaderSize(0), totalSize(0) {} + + // Simple way to tell if data is valid + uint64_t eyeCatch; + // Track version in case there are compatibility issues + uint64_t version; + // Offset to branchtable from start of secureROM + uint64_t branchtableOffset; + // pointer to start of secureROM code + const void* secureRom; + // size of entire secureROM + size_t secureRomSize; + // pointer to the hw keys hash used for verification + const void* hwKeysHash; + // size of key + size_t hwKeysHashSize; + // pointer to the saved off Hostboot base header for TPM extension + const void* hbbHeader; + // size of Hostboot base header + size_t hbbHeaderSize; + // Total size of data preserved by the Kernel + size_t totalSize; +} __attribute__((packed)); + +/** + * @brief Checks if Bootloader to hostboot data is valid by checking the + * eyeCatch and version + * + * @param[in] BlToHbData* Pointer to BlToHbdata. Must not be NULL + * + * @return bool true if valid; false otherwise + */ +inline bool BlToHbDataValid (const BlToHbData * i_blToHbData) +{ + // Ensure Version and EyeCatch are valid + return (i_blToHbData->eyeCatch == BLTOHB_EYECATCHER) && + (i_blToHbData->version >= BLTOHB_INIT); +} + +} // end namespace bootloader + #endif
\ No newline at end of file |