security/vboot: Add store/validate methods for AMD VBIOS FMAP cache
Add methods to store and retrieve the hash of the data stored in the VBIOS cache FMAP region. Add a dedicated index in TPM NVRAM to store the hash, and methods to calculate/read/write it. Modeled after mrc_cache_hash_tpm.{c,h} BUG=b:255812886 TEST=tested with rest of patch train Change-Id: I030017d3bf956b8593bc09073ad6545b80a5b52b Signed-off-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/72401 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
This commit is contained in:
parent
e47d9fd3b6
commit
9ce755d05e
|
@ -127,6 +127,8 @@ postcar-y += common.c
|
|||
romstage-$(CONFIG_MRC_SAVE_HASH_IN_TPM) += mrc_cache_hash_tpm.c
|
||||
ramstage-$(CONFIG_MRC_SAVE_HASH_IN_TPM) += mrc_cache_hash_tpm.c
|
||||
|
||||
ramstage-$(CONFIG_SOC_AMD_GFX_CACHE_VBIOS_IN_FMAP) += vbios_cache_hash_tpm.c
|
||||
|
||||
ifeq ($(CONFIG_VBOOT_SEPARATE_VERSTAGE),y)
|
||||
|
||||
$(eval $(call vboot-for-stage,verstage))
|
||||
|
|
|
@ -29,6 +29,7 @@ enum vb2_pcr_digest;
|
|||
#define MRC_RW_HASH_NV_INDEX 0x100d
|
||||
#define HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE
|
||||
#define ENT_ROLLBACK_SPACE_INDEX 0x100e
|
||||
#define VBIOS_CACHE_NV_INDEX 0x100f
|
||||
/* Widevine Secure Counter space */
|
||||
#define WIDEVINE_COUNTER_NV_INDEX(n) (0x3000 + (n))
|
||||
#define NUM_WIDEVINE_COUNTERS 4
|
||||
|
@ -99,4 +100,17 @@ uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data,
|
|||
*/
|
||||
uint32_t antirollback_lock_space_mrc_hash(uint32_t index);
|
||||
|
||||
/*
|
||||
* Read VBIOS hash data from TPM.
|
||||
* @param data pointer to buffer where hash from TPM read into
|
||||
* @param size size of buffer
|
||||
*/
|
||||
uint32_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size);
|
||||
/*
|
||||
* Write new hash data to VBIOS space in TPM.
|
||||
* @param data pointer to buffer of hash value to be written
|
||||
* @param size size of buffer
|
||||
*/
|
||||
uint32_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size);
|
||||
|
||||
#endif /* ANTIROLLBACK_H_ */
|
||||
|
|
|
@ -69,3 +69,13 @@ vb2_error_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *dat
|
|||
{
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
vb2_error_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
|
||||
{
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
||||
vb2_error_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
|
||||
{
|
||||
return VB2_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -481,6 +481,52 @@ uint32_t antirollback_lock_space_mrc_hash(uint32_t index)
|
|||
return tlcl_lock_nv_write(index);
|
||||
}
|
||||
|
||||
static uint32_t read_space_vbios_hash(uint8_t *data)
|
||||
{
|
||||
RETURN_ON_FAILURE(tlcl_read(VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE));
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t antirollback_read_space_vbios_hash(uint8_t *data, uint32_t size)
|
||||
{
|
||||
if (size != HASH_NV_SIZE) {
|
||||
VBDEBUG("TPM: Incorrect buffer size for hash idx 0x%x. "
|
||||
"(Expected=0x%x Actual=0x%x).\n", VBIOS_CACHE_NV_INDEX, HASH_NV_SIZE,
|
||||
size);
|
||||
return TPM_E_READ_FAILURE;
|
||||
}
|
||||
return read_space_vbios_hash(data);
|
||||
}
|
||||
|
||||
uint32_t antirollback_write_space_vbios_hash(const uint8_t *data, uint32_t size)
|
||||
{
|
||||
uint8_t spc_data[HASH_NV_SIZE];
|
||||
uint32_t rv;
|
||||
|
||||
if (size != HASH_NV_SIZE) {
|
||||
VBDEBUG("TPM: Incorrect buffer size for hash idx 0x%x. "
|
||||
"(Expected=0x%x Actual=0x%x).\n", VBIOS_CACHE_NV_INDEX, HASH_NV_SIZE,
|
||||
size);
|
||||
return TPM_E_WRITE_FAILURE;
|
||||
}
|
||||
|
||||
rv = read_space_vbios_hash(spc_data);
|
||||
if (rv == TPM_E_BADINDEX) {
|
||||
/*
|
||||
* If space is not defined already for hash, define
|
||||
* new space.
|
||||
*/
|
||||
VBDEBUG("TPM: Initializing hash space.\n");
|
||||
return setup_space("VBIOS Cache Hash", VBIOS_CACHE_NV_INDEX, data, HASH_NV_SIZE,
|
||||
rw_space_attributes, NULL, 0);
|
||||
}
|
||||
|
||||
if (rv != TPM_SUCCESS)
|
||||
return rv;
|
||||
|
||||
return safe_write(VBIOS_CACHE_NV_INDEX, data, size);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <security/vboot/antirollback.h>
|
||||
#include <program_loading.h>
|
||||
#include <vb2_api.h>
|
||||
#include <security/tpm/tss.h>
|
||||
#include <security/vboot/misc.h>
|
||||
#include <security/vboot/vbios_cache_hash_tpm.h>
|
||||
#include <console/console.h>
|
||||
#include <string.h>
|
||||
|
||||
void vbios_cache_update_hash(const uint8_t *data, size_t size)
|
||||
{
|
||||
struct vb2_hash hash;
|
||||
|
||||
/* Initialize TPM driver. */
|
||||
if (tlcl_lib_init() != VB2_SUCCESS) {
|
||||
printk(BIOS_ERR, "VBIOS_CACHE: TPM driver initialization failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate hash of vbios data. */
|
||||
if (vb2_hash_calculate(vboot_hwcrypto_allowed(), data, size,
|
||||
VB2_HASH_SHA256, &hash)) {
|
||||
printk(BIOS_ERR, "VBIOS_CACHE: SHA-256 calculation failed for data; "
|
||||
"clearing TPM hash space.\n");
|
||||
/*
|
||||
* Since data is being updated in vbios cache, the hash
|
||||
* currently stored in TPM hash space is no longer
|
||||
* valid. If we are not able to calculate hash of the
|
||||
* data being updated, reset all the bits in TPM hash
|
||||
* space to zero to invalidate it.
|
||||
*/
|
||||
memset(hash.raw, 0, VB2_SHA256_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
/* Write hash of data to TPM space. */
|
||||
if (antirollback_write_space_vbios_hash(hash.sha256, sizeof(hash.sha256))
|
||||
!= TPM_SUCCESS) {
|
||||
printk(BIOS_ERR, "VBIOS_CACHE: Could not save hash to TPM.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "VBIOS_CACHE: TPM NV idx 0x%x updated successfully.\n",
|
||||
VBIOS_CACHE_NV_INDEX);
|
||||
}
|
||||
|
||||
enum cb_err vbios_cache_verify_hash(const uint8_t *data, size_t size)
|
||||
{
|
||||
struct vb2_hash tpm_hash = { .algo = VB2_HASH_SHA256 };
|
||||
|
||||
/* Initialize TPM driver. */
|
||||
if (tlcl_lib_init() != VB2_SUCCESS) {
|
||||
printk(BIOS_ERR, "VBIOS_CACHE: TPM driver initialization failed.\n");
|
||||
return CB_ERR;
|
||||
}
|
||||
|
||||
/* Read hash of VBIOS data saved in TPM. */
|
||||
if (antirollback_read_space_vbios_hash(tpm_hash.sha256, sizeof(tpm_hash.sha256))
|
||||
!= TPM_SUCCESS) {
|
||||
printk(BIOS_ERR, "VBIOS_CACHE: Could not read hash from TPM.\n");
|
||||
return CB_ERR;
|
||||
}
|
||||
|
||||
/* Calculate hash of data read from VBIOS FMAP CACHE and compare. */
|
||||
if (vb2_hash_verify(vboot_hwcrypto_allowed(), data, size, &tpm_hash)) {
|
||||
printk(BIOS_ERR, "VBIOS_CACHE: Hash comparison failed.\n");
|
||||
return CB_ERR;
|
||||
}
|
||||
|
||||
printk(BIOS_INFO, "VBIOS_CACHE: Hash idx 0x%x comparison successful.\n",
|
||||
VBIOS_CACHE_NV_INDEX);
|
||||
|
||||
return CB_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _VBIOS_CACHE_HASH_TPM_H_
|
||||
#define _VBIOS_CACHE_HASH_TPM_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
* Updates vbios cache hash.
|
||||
*/
|
||||
void vbios_cache_update_hash(const uint8_t *data, size_t size);
|
||||
|
||||
/*
|
||||
* Verifies vbios cache hash which is stored in FMAP region.
|
||||
*/
|
||||
enum cb_err vbios_cache_verify_hash(const uint8_t *data, size_t size);
|
||||
|
||||
#endif /* _VBIOS_CACHE_HASH_TPM_H_ */
|
Loading…
Reference in New Issue