diff --git a/src/soc/intel/apollolake/Makefile.mk b/src/soc/intel/apollolake/Makefile.mk index ea3e05aebf..8dc4b5fd46 100644 --- a/src/soc/intel/apollolake/Makefile.mk +++ b/src/soc/intel/apollolake/Makefile.mk @@ -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 diff --git a/src/soc/intel/apollolake/include/soc/fit.h b/src/soc/intel/apollolake/include/soc/fit.h new file mode 100644 index 0000000000..fa81e6e42e --- /dev/null +++ b/src/soc/intel/apollolake/include/soc/fit.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _FIT_H_ +#define _FIT_H_ + +#include + +#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_ */ diff --git a/src/soc/intel/apollolake/include/soc/measured_boot.h b/src/soc/intel/apollolake/include/soc/measured_boot.h new file mode 100644 index 0000000000..e6e06f3f08 --- /dev/null +++ b/src/soc/intel/apollolake/include/soc/measured_boot.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _BOOT_GUARD_LIB_H_ +#define _BOOT_GUARD_LIB_H_ + +#include + +/* 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_ */ diff --git a/src/soc/intel/apollolake/measured_boot.c b/src/soc/intel/apollolake/measured_boot.c new file mode 100644 index 0000000000..8f1d1ee321 --- /dev/null +++ b/src/soc/intel/apollolake/measured_boot.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +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"); + } + } +}