aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/amd/phoenix/psp_verstage/chipset.c121
-rw-r--r--src/soc/amd/phoenix/psp_verstage/svc.c7
-rw-r--r--src/soc/amd/phoenix/psp_verstage/svc.h2
-rw-r--r--src/vendorcode/amd/fsp/phoenix/include/bl_uapp/bl_syscall_public.h29
4 files changed, 129 insertions, 30 deletions
diff --git a/src/soc/amd/phoenix/psp_verstage/chipset.c b/src/soc/amd/phoenix/psp_verstage/chipset.c
index acbd55954f..cf03272b96 100644
--- a/src/soc/amd/phoenix/psp_verstage/chipset.c
+++ b/src/soc/amd/phoenix/psp_verstage/chipset.c
@@ -11,51 +11,40 @@
#include <security/vboot/misc.h>
#include <security/vboot/vbnv.h>
+#define PSP_FW_HASH_FILE_NAME(slot, id) "apu/amdfw_" slot "_hash" id
/*
* 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.
*/
-#define MAX_NUM_HASH_ENTRIES 128
+#define MAX_NUM_HASH_ENTRIES 64
static struct psp_fw_hash_table hash_table;
static struct psp_fw_entry_hash_256 hash_256[MAX_NUM_HASH_ENTRIES];
static struct psp_fw_entry_hash_384 hash_384[MAX_NUM_HASH_ENTRIES];
-void update_psp_fw_hash_table(const char *fname)
+static struct psp_fw_hash_table_v2 hash_table_v2;
+static struct psp_fw_entry_hash_256_v2 hash_256_v2[MAX_NUM_HASH_ENTRIES];
+static struct psp_fw_entry_hash_384_v2 hash_384_v2[MAX_NUM_HASH_ENTRIES];
+
+static void update_one_psp_fw_hash_table_v1(enum verstage_cmd_id cmd, uint8_t *spi_ptr)
{
- void *hash_file = cbfs_map(fname, NULL);
- uint8_t *spi_ptr = (uint8_t *)hash_file;
uint32_t len;
- if (!spi_ptr) {
- printk(BIOS_ERR, "AMD Firmware hash table %s not found\n", fname);
- /*
- * 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, offsetof(struct psp_fw_hash_table, fw_hash_256));
if (hash_table.no_of_entries_256 > MAX_NUM_HASH_ENTRIES ||
hash_table.no_of_entries_384 > MAX_NUM_HASH_ENTRIES) {
printk(BIOS_ERR, "Too many entries in AMD Firmware hash table"
- " (SHA256:%d, SHA384:%d)\n",
- hash_table.no_of_entries_256, hash_table.no_of_entries_384);
- cbfs_unmap(hash_file);
- rdev_munmap(boot_device_ro(), hash_file);
+ " (SHA256:%d, SHA384:%d)\n", hash_table.no_of_entries_256,
+ hash_table.no_of_entries_384);
return;
}
- if (hash_table.no_of_entries_256 == 0 &&
- hash_table.no_of_entries_384 == 0) {
+ if (hash_table.no_of_entries_256 == 0 && hash_table.no_of_entries_384 == 0) {
printk(BIOS_ERR, "No entries in AMD Firmware hash table"
- " (SHA256:%d, SHA384:%d)\n",
- hash_table.no_of_entries_256, hash_table.no_of_entries_384);
- cbfs_unmap(hash_file);
- rdev_munmap(boot_device_ro(), hash_file);
+ " (SHA256:%d, SHA384:%d)\n", hash_table.no_of_entries_256,
+ hash_table.no_of_entries_384);
return;
}
@@ -70,11 +59,95 @@ void update_psp_fw_hash_table(const char *fname)
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);
+ svc_set_fw_hash_table(cmd, &hash_table);
+}
+
+static void update_one_psp_fw_hash_table_v2(enum verstage_cmd_id cmd, uint8_t *spi_ptr)
+{
+ uint32_t len;
+
+ memcpy(&hash_table_v2, spi_ptr, offsetof(struct psp_fw_hash_table_v2, fw_hash_256));
+
+ if (hash_table_v2.no_of_entries_256 > MAX_NUM_HASH_ENTRIES ||
+ hash_table_v2.no_of_entries_384 > MAX_NUM_HASH_ENTRIES) {
+ printk(BIOS_ERR, "Too many entries in AMD Firmware hash table"
+ " (SHA256:%d, SHA384:%d)\n", hash_table_v2.no_of_entries_256,
+ hash_table_v2.no_of_entries_384);
+ return;
+ }
+
+ if (hash_table_v2.no_of_entries_256 == 0 && hash_table_v2.no_of_entries_384 == 0) {
+ printk(BIOS_ERR, "No entries in AMD Firmware hash table"
+ " (SHA256:%d, SHA384:%d)\n", hash_table_v2.no_of_entries_256,
+ hash_table_v2.no_of_entries_384);
+ return;
+ }
+
+ spi_ptr += offsetof(struct psp_fw_hash_table_v2, fw_hash_256);
+
+ hash_table_v2.fw_hash_256 = hash_256_v2;
+ hash_table_v2.fw_hash_384 = hash_384_v2;
+ len = sizeof(struct psp_fw_entry_hash_256_v2) * hash_table_v2.no_of_entries_256;
+ memcpy(hash_256_v2, spi_ptr, len);
+
+ spi_ptr += len;
+ len = sizeof(struct psp_fw_entry_hash_384_v2) * hash_table_v2.no_of_entries_384;
+ memcpy(hash_384_v2, spi_ptr, len);
+
+ svc_set_fw_hash_table(cmd, &hash_table_v2);
+}
+
+static void update_one_psp_fw_hash_table(enum verstage_cmd_id cmd, const char *fname)
+{
+ void *hash_file = cbfs_map(fname, NULL);
+ uint16_t version;
+
+ if (!hash_file) {
+ printk(BIOS_ERR, "AMD Firmware hash table %s not found\n", fname);
+ /*
+ * If we don't supply hash table, the PSP will refuse to boot.
+ * So returning here is safe to do.
+ */
+ return;
+ }
+
+ memcpy(&version, hash_file, sizeof(version));
+ assert(version <= 2);
+ switch (version) {
+ case 1:
+ update_one_psp_fw_hash_table_v1(cmd, hash_file);
+ break;
+ case 2:
+ update_one_psp_fw_hash_table_v2(cmd, hash_file);
+ break;
+ default:
+ printk(BIOS_ERR, "%s: Unexpected version %d\n", __func__, version);
+ }
cbfs_unmap(hash_file);
rdev_munmap(boot_device_ro(), hash_file);
}
+void update_psp_fw_hash_tables(void)
+{
+ struct vb2_context *ctx = vboot_get_context();
+
+ if (vboot_is_firmware_slot_a(ctx)) {
+ update_one_psp_fw_hash_table(CMD_SET_FW_HASH_TABLE_STAGE1,
+ PSP_FW_HASH_FILE_NAME("a", ""));
+ update_one_psp_fw_hash_table(CMD_SET_FW_HASH_TABLE_STAGE2,
+ PSP_FW_HASH_FILE_NAME("a", "1"));
+ update_one_psp_fw_hash_table(CMD_SET_FW_HASH_TABLE_TOS,
+ PSP_FW_HASH_FILE_NAME("a", "2"));
+ } else {
+ update_one_psp_fw_hash_table(CMD_SET_FW_HASH_TABLE_STAGE1,
+ PSP_FW_HASH_FILE_NAME("a", ""));
+ update_one_psp_fw_hash_table(CMD_SET_FW_HASH_TABLE_STAGE2,
+ PSP_FW_HASH_FILE_NAME("a", "1"));
+ update_one_psp_fw_hash_table(CMD_SET_FW_HASH_TABLE_TOS,
+ PSP_FW_HASH_FILE_NAME("a", "2"));
+ }
+}
+
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/phoenix/psp_verstage/svc.c b/src/soc/amd/phoenix/psp_verstage/svc.c
index c88f7598f7..45d18c1456 100644
--- a/src/soc/amd/phoenix/psp_verstage/svc.c
+++ b/src/soc/amd/phoenix/psp_verstage/svc.c
@@ -206,13 +206,16 @@ uint32_t svc_set_platform_boot_mode(enum chrome_platform_boot_mode boot_mode)
return retval;
}
-uint32_t svc_set_fw_hash_table(struct psp_fw_hash_table *hash_table)
+uint32_t svc_set_fw_hash_table(enum verstage_cmd_id cmd, void *hash_table)
{
uint32_t retval = 0;
struct cmd_param_set_fw_hash_table param = {
.ptr_psp_fw_hash_table = hash_table,
};
- SVC_CALL2(SVC_VERSTAGE_CMD, CMD_SET_FW_HASH_TABLE, (void *)&param, retval);
+ assert(cmd == CMD_SET_FW_HASH_TABLE_STAGE1 ||
+ cmd == CMD_SET_FW_HASH_TABLE_STAGE2 ||
+ cmd == CMD_SET_FW_HASH_TABLE_TOS);
+ SVC_CALL2(SVC_VERSTAGE_CMD, cmd, (void *)&param, retval);
return retval;
}
diff --git a/src/soc/amd/phoenix/psp_verstage/svc.h b/src/soc/amd/phoenix/psp_verstage/svc.h
index c3e6475ca9..43b560a8a9 100644
--- a/src/soc/amd/phoenix/psp_verstage/svc.h
+++ b/src/soc/amd/phoenix/psp_verstage/svc.h
@@ -92,7 +92,7 @@ struct cmd_param_set_platform_boot_mode {
};
struct cmd_param_set_fw_hash_table {
- struct psp_fw_hash_table *ptr_psp_fw_hash_table;
+ void *ptr_psp_fw_hash_table;
};
struct cmd_param_get_prev_boot_status {
diff --git a/src/vendorcode/amd/fsp/phoenix/include/bl_uapp/bl_syscall_public.h b/src/vendorcode/amd/fsp/phoenix/include/bl_uapp/bl_syscall_public.h
index 623762ad0e..b3e41404e8 100644
--- a/src/vendorcode/amd/fsp/phoenix/include/bl_uapp/bl_syscall_public.h
+++ b/src/vendorcode/amd/fsp/phoenix/include/bl_uapp/bl_syscall_public.h
@@ -60,6 +60,9 @@ enum verstage_cmd_id {
CMD_GET_PREV_BOOT_STATUS,
CMD_GET_HSP_SECURE_STATE,
CMD_WRITE_POSTCODE,
+ CMD_SET_FW_HASH_TABLE_STAGE1,
+ CMD_SET_FW_HASH_TABLE_STAGE2,
+ CMD_SET_FW_HASH_TABLE_TOS,
};
struct mod_exp_params {
@@ -178,13 +181,32 @@ struct psp_fw_entry_hash_384 {
} __packed;
struct psp_fw_hash_table {
- uint16_t version; // Version of psp_fw_hash_table, Start with 0.
+ uint16_t version; // Version 1 of psp_fw_hash_table.
uint16_t no_of_entries_256;
uint16_t no_of_entries_384;
struct psp_fw_entry_hash_256 *fw_hash_256;
struct psp_fw_entry_hash_384 *fw_hash_384;
} __packed;
+struct psp_fw_entry_hash_256_v2 {
+ uint8_t uuid[16];
+ uint8_t sha[32];
+} __packed;
+
+struct psp_fw_entry_hash_384_v2 {
+ uint8_t uuid[16];
+ uint8_t sha[48];
+} __packed;
+
+struct psp_fw_hash_table_v2 {
+ uint16_t version; // Version 2 of psp_fw_hash_table.
+ uint16_t no_of_entries_256;
+ uint16_t no_of_entries_384;
+ uint16_t reserved; // For alignment purposes.
+ struct psp_fw_entry_hash_256_v2 *fw_hash_256;
+ struct psp_fw_entry_hash_384_v2 *fw_hash_384;
+} __packed;
+
/*
* Exit to the main Boot Loader. This does not return back to user application.
*
@@ -372,14 +394,15 @@ uint32_t svc_ccp_dma(uint32_t spi_rom_offset, void *dest, uint32_t size);
uint32_t svc_set_platform_boot_mode(enum chrome_platform_boot_mode boot_mode);
/*
- * Set the PSP FW hash table.
+ * Set PSP FW hash table.
*
* Parameters:
* - hash_table - Table of hash for each PSP binary signed against SoC chain of trust
+ * - cmd - Cmd to indicate the PSP stage using the hash table
*
* Return value: BL_OK or error code
*/
-uint32_t svc_set_fw_hash_table(struct psp_fw_hash_table *hash_table);
+uint32_t svc_set_fw_hash_table(enum verstage_cmd_id cmd, void *hash_table);
/* Get the previous boot status.
*