Skip to content

Commit

Permalink
Check if securerom is valid and fill in bl to hb struct
Browse files Browse the repository at this point in the history
The bootloader to hostboot structure is data that is filled
in by the bootloader and used by hostboot code. This is used
for things like getting the securerom code, hwkeyshash, and
hbb header

Change-Id: I04a228b0f1d5a6f6d0b02bf87f3564f6ef95e7a3
RTC: 166848
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35762
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
Stephen Cprek authored and dcrowell77 committed Mar 8, 2017
1 parent 51438e2 commit 2475464
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 40 deletions.
114 changes: 74 additions & 40 deletions src/bootloader/bootloader.C
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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));
}

/**
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down
78 changes: 78 additions & 0 deletions src/include/bootloader/bootloaderif.H
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,89 @@
#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)

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

0 comments on commit 2475464

Please sign in to comment.