soc/intel/apollolake: Add support for IFWI Measured Boot
Add Measured Boot that is specific to Apollolake, and is used for measuring the IBBL, IBB and TXE. The IBB is measured only if it exists, and only after it has been loaded into the CSE. Signed-off-by: Sean Rhodes <sean@starlabs.systems> Change-Id: I61ce4a34875d6d3357d4088167cdd887bafdff23 Reviewed-on: https://review.coreboot.org/c/coreboot/+/65272 Reviewed-by: Werner Zeh <werner.zeh@siemens.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: David Hendricks <david.hendricks@gmail.com>
This commit is contained in:
parent
289cff3423
commit
0b5ce9d9f0
4 changed files with 173 additions and 0 deletions
|
|
@ -7,6 +7,7 @@ subdirs-y += ../../../cpu/intel/turbo
|
|||
|
||||
bootblock-$(CONFIG_TPM_MEASURED_BOOT) += bootblock/bootblock_measure.c
|
||||
bootblock-y += bootblock/bootblock.c
|
||||
bootblock-$(CONFIG_IFWI_MEASURED_BOOT) += measured_boot.c
|
||||
bootblock-y += ../common/block/cpu/pm_timer_emulation.c
|
||||
bootblock-y += car.c
|
||||
bootblock-y += heci.c
|
||||
|
|
|
|||
27
src/soc/intel/apollolake/include/soc/fit.h
Normal file
27
src/soc/intel/apollolake/include/soc/fit.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _FIT_H_
|
||||
#define _FIT_H_
|
||||
|
||||
#include <vendorcode/intel/edk2/uefi_2.4/uefi_types.h>
|
||||
|
||||
#define FIT_TABLE_SIGNATURE SIGNATURE_64('_', 'F', 'I', 'T', '_', ' ', ' ', ' ')
|
||||
|
||||
#define FIT_TABLE_TYPE_HEADER 0x0
|
||||
#define FIT_TABLE_TYPE_TXE_SECURE_BOOT 0x10
|
||||
#define FIT_ENTRY_SUB_TYPE_TXE_HASH 0x2
|
||||
#define FIT_ENTRY_SUB_TYPE_BOOT_POLICY 0x3
|
||||
#define FIT_ENTRY_SUB_TYPE_IBBL_HASH 0x7
|
||||
#define FIT_ENTRY_SUB_TYPE_IBB_HASH 0x8
|
||||
|
||||
struct firmware_interface_table_entry {
|
||||
uint64_t address;
|
||||
uint8_t size[3];
|
||||
uint8_t sub_type;
|
||||
uint16_t version;
|
||||
uint8_t type: 7;
|
||||
uint8_t cv: 1;
|
||||
uint8_t chk_sum;
|
||||
};
|
||||
|
||||
#endif /* _FIT_H_ */
|
||||
31
src/soc/intel/apollolake/include/soc/measured_boot.h
Normal file
31
src/soc/intel/apollolake/include/soc/measured_boot.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _BOOT_GUARD_LIB_H_
|
||||
#define _BOOT_GUARD_LIB_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/* Boot Policy configuration for Boot Guard */
|
||||
struct boot_policy {
|
||||
uint16_t pbe: 1;
|
||||
uint16_t bbi: 1;
|
||||
uint16_t vb: 1;
|
||||
uint16_t mb: 1;
|
||||
uint16_t kmid: 4;
|
||||
uint16_t dcd: 1;
|
||||
uint16_t sb_s3_opt: 1;
|
||||
uint16_t res: 6;
|
||||
};
|
||||
|
||||
/* Boot Policy info populated by TXE */
|
||||
struct boot_policy_manifest {
|
||||
struct boot_policy bpm;
|
||||
uint8_t txe_hash[SHA256_DIGEST_SIZE];
|
||||
uint8_t ibbl_hash[32];
|
||||
uint8_t ibb_hash[32];
|
||||
};
|
||||
|
||||
bool fetch_pre_rbp_data(struct boot_policy_manifest *bpm_info);
|
||||
void fetch_post_rbp_data(struct boot_policy_manifest *bpm_info);
|
||||
|
||||
#endif /* _BOOT_GUARD_LIB_H_ */
|
||||
114
src/soc/intel/apollolake/measured_boot.c
Normal file
114
src/soc/intel/apollolake/measured_boot.c
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/mmio.h>
|
||||
#include <lib.h>
|
||||
#include <security/tpm/tspi.h>
|
||||
#include <security/tpm/tss/tcg-2.0/tss_structures.h>
|
||||
#include <soc/measured_boot.h>
|
||||
#include <soc/fit.h>
|
||||
#include <string.h>
|
||||
|
||||
extern const uint64_t fit_ptr;
|
||||
|
||||
static void *find_fit_entry_data(uint8_t type, uint8_t sub_type)
|
||||
{
|
||||
struct firmware_interface_table_entry *fit_entry;
|
||||
uint32_t entry_num;
|
||||
uint32_t fit_table_offset;
|
||||
uint32_t index;
|
||||
|
||||
fit_table_offset = fit_ptr;
|
||||
fit_entry = (struct firmware_interface_table_entry *)(uint32_t)fit_table_offset;
|
||||
if (fit_entry[0].address != FIT_TABLE_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
if (fit_entry[0].type != FIT_TABLE_TYPE_HEADER)
|
||||
return NULL;
|
||||
|
||||
entry_num = *(uint32_t *)(&fit_entry[0].size[0]) & 0xffffff;
|
||||
for (index = 0; index < entry_num; index++) {
|
||||
if ((fit_entry[index].type == type) && (fit_entry[index].sub_type == sub_type))
|
||||
return (void *)(uint32_t)fit_entry[index].address;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool fetch_pre_rbp_data(struct boot_policy_manifest *bpm_info)
|
||||
{
|
||||
uint8_t *fit_data;
|
||||
fit_data = find_fit_entry_data(FIT_TABLE_TYPE_TXE_SECURE_BOOT,
|
||||
FIT_ENTRY_SUB_TYPE_BOOT_POLICY);
|
||||
|
||||
if (fit_data != NULL) {
|
||||
memcpy((void *)&(bpm_info->bpm), fit_data, sizeof(bpm_info->bpm));
|
||||
|
||||
printk(BIOS_DEBUG, "Boot Guard 2.0: Verified Boot: %s\n",
|
||||
bpm_info->bpm.vb ? "Enforced" : "Not enforced");
|
||||
if (bpm_info->bpm.vb && !CONFIG(IFWI_VERIFIED_BOOT))
|
||||
printk(BIOS_CRIT, "Boot Guard 2.0: Verified boot is enforced but not enabled.\n");
|
||||
|
||||
printk(BIOS_DEBUG, "Boot Guard 2.0: Measured Boot: %s\n",
|
||||
bpm_info->bpm.mb ? "Enforced" : "Not enforced");
|
||||
if (bpm_info->bpm.mb && !CONFIG(IFWI_MEASURED_BOOT))
|
||||
printk(BIOS_CRIT, "Boot Guard 2.0: Measured boot is enforced but not enabled.\n");
|
||||
}
|
||||
|
||||
if (CONFIG(IFWI_MEASURED_BOOT)) {
|
||||
/* TXE */
|
||||
fit_data = find_fit_entry_data(FIT_TABLE_TYPE_TXE_SECURE_BOOT,
|
||||
FIT_ENTRY_SUB_TYPE_TXE_HASH);
|
||||
if (fit_data) {
|
||||
memcpy((void *)(bpm_info->txe_hash), fit_data,
|
||||
sizeof(bpm_info->txe_hash));
|
||||
printk(BIOS_DEBUG, "TXE Hash: %hhn\n", bpm_info->txe_hash);
|
||||
hexdump((void *)bpm_info->txe_hash, SHA256_DIGEST_SIZE);
|
||||
|
||||
tpm_extend_pcr(0, TPM_ALG_SHA256, bpm_info->txe_hash,
|
||||
SHA256_DIGEST_SIZE, "TXE");
|
||||
}
|
||||
|
||||
/* IBBL */
|
||||
fit_data = find_fit_entry_data(FIT_TABLE_TYPE_TXE_SECURE_BOOT,
|
||||
FIT_ENTRY_SUB_TYPE_IBBL_HASH);
|
||||
if (fit_data) {
|
||||
memcpy((void *)(bpm_info->ibbl_hash), fit_data,
|
||||
sizeof(bpm_info->ibbl_hash));
|
||||
printk(BIOS_DEBUG, "IBBL Hash: %hhn\n", bpm_info->ibbl_hash);
|
||||
hexdump((void *)bpm_info->ibbl_hash, SHA256_DIGEST_SIZE);
|
||||
|
||||
tpm_extend_pcr(0, TPM_ALG_SHA256, bpm_info->ibbl_hash,
|
||||
SHA256_DIGEST_SIZE, "IBBL");
|
||||
|
||||
}
|
||||
/* Return if IBB exists */
|
||||
fit_data = find_fit_entry_data(FIT_TABLE_TYPE_TXE_SECURE_BOOT,
|
||||
FIT_ENTRY_SUB_TYPE_IBB_HASH);
|
||||
|
||||
printk(BIOS_DEBUG, "IBB: %s\n", fit_data ? "Present" : "Not present");
|
||||
return fit_data;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fetch_post_rbp_data(struct boot_policy_manifest *bpm_info)
|
||||
{
|
||||
if (CONFIG(IFWI_MEASURED_BOOT)) {
|
||||
/* IBB */
|
||||
uint8_t *fit_data;
|
||||
fit_data = find_fit_entry_data(FIT_TABLE_TYPE_TXE_SECURE_BOOT,
|
||||
FIT_ENTRY_SUB_TYPE_IBB_HASH);
|
||||
|
||||
if (fit_data) {
|
||||
memcpy((void *)bpm_info->ibb_hash, fit_data,
|
||||
sizeof(bpm_info->ibb_hash));
|
||||
printk(BIOS_DEBUG, "IBB Hash: %hhn\n", bpm_info->ibb_hash);
|
||||
hexdump((void *)bpm_info->ibb_hash, SHA256_DIGEST_SIZE);
|
||||
|
||||
tpm_extend_pcr(0, TPM_ALG_SHA256, bpm_info->ibb_hash,
|
||||
SHA256_DIGEST_SIZE, "IBBM");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue