Attention is currently required from: Jason Glenesk, Raul Rangel, Marshall Dawson, Felix Held. Kangheui Won has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/60291 )
Change subject: soc/amd/cezanne: pass psp fw hash table ......................................................................
soc/amd/cezanne: pass psp fw hash table
Copy AMD PSP fw hash table into memory, then pass it to the PSP. The PSP will use this hash to verify it's the correct firmware bundled with coreboot build and not replaced.
BUG=b:203597980 TEST=dump hash table in the verstage
Signed-off-by: Kangheui Won khwon@chromium.org Change-Id: I84bea97c89620d0388b27891a898ffde77052239 --- M src/soc/amd/cezanne/psp_verstage/chipset.c M src/soc/amd/common/psp_verstage/include/psp_verstage.h M src/soc/amd/common/psp_verstage/psp_verstage.c 3 files changed, 57 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/91/60291/1
diff --git a/src/soc/amd/cezanne/psp_verstage/chipset.c b/src/soc/amd/cezanne/psp_verstage/chipset.c index 183f116..b532019 100644 --- a/src/soc/amd/cezanne/psp_verstage/chipset.c +++ b/src/soc/amd/cezanne/psp_verstage/chipset.c @@ -1,8 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */
#include <bl_uapp/bl_syscall_public.h> +#include <cbfs.h> +#include <console/console.h> #include <psp_verstage.h>
+/* + * We can't pass pointer to hash table in the SPI. + * The AMD PSP team specifically required that whole hash table + * should be copied into memory before passing them to the PSP + * to reduce window of TOCTOU. + * + */ +static struct psp_fw_hash_table hash_table; +static struct psp_fw_entry_hash_256 hash_256[128]; +static struct psp_fw_entry_hash_384 hash_384[128]; + +void update_psp_fw_hash_table(const char *fname) +{ + uint8_t *spi_ptr = (uint8_t *)cbfs_map(fname, NULL); + uint32_t len; + + if (!spi_ptr) { + printk(BIOS_ERR, "Error: AMD Firmware hash table not found\n"); + /* + * If we don't supply hash table, the PSP will refuse to boot. + * So returning here is safe to do. + * */ + return; + } + + memcpy(&hash_table, spi_ptr, sizeof(hash_table)); + + if (hash_table.no_of_entries_256 > 128 || + hash_table.no_of_entries_384 > 128) { + printk(BIOS_ERR, "Error: Too many entries in AMD Firmware hash table\n"); + return; + } + + spi_ptr += sizeof(struct psp_fw_hash_table); + + hash_table.fw_hash_256 = hash_256; + hash_table.fw_hash_384 = hash_384; + len = sizeof(struct psp_fw_entry_hash_256) * hash_table.no_of_entries_256; + memcpy(hash_256, spi_ptr, len); + + spi_ptr += len; + len = sizeof(struct psp_fw_entry_hash_384) * hash_table.no_of_entries_384; + memcpy(hash_384, spi_ptr, len); + + svc_set_fw_hash_table(&hash_table); +} + uint32_t update_psp_bios_dir(uint32_t *psp_dir_offset, uint32_t *bios_dir_offset) { return svc_update_psp_bios_dir(psp_dir_offset, bios_dir_offset); diff --git a/src/soc/amd/common/psp_verstage/include/psp_verstage.h b/src/soc/amd/common/psp_verstage/include/psp_verstage.h index 606b6a6..7924ce5 100644 --- a/src/soc/amd/common/psp_verstage/include/psp_verstage.h +++ b/src/soc/amd/common/psp_verstage/include/psp_verstage.h @@ -66,4 +66,6 @@ int platform_set_sha_op(enum vb2_hash_algorithm hash_alg, struct sha_generic_data *sha_op);
+void update_psp_fw_hash_table(const char *fname); + #endif /* PSP_VERSTAGE_H */ diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c index 05c14d6..b959df4 100644 --- a/src/soc/amd/common/psp_verstage/psp_verstage.c +++ b/src/soc/amd/common/psp_verstage/psp_verstage.c @@ -83,6 +83,7 @@ uint32_t psp_dir_addr, bios_dir_addr; uint32_t *psp_dir_in_spi, *bios_dir_in_spi; const char *fname; + const char *hash_fname; void *amdfw_location; void *boot_dev_base = rdev_mmap_full(boot_device_ro());
@@ -94,8 +95,10 @@
if (vboot_is_firmware_slot_a(ctx)) { fname = "apu/amdfw_a"; + hash_fname = "apu/amdfw_a_hash"; } else { fname = "apu/amdfw_b"; + hash_fname = "apu/amdfw_b_hash"; }
amdfw_location = cbfs_map(fname, NULL); @@ -135,6 +138,9 @@ return POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR; }
+ if (CONFIG(SEPARATE_SIGNED_AMDFW)) + update_psp_fw_hash_table(hash_fname); + return 0; }