Pull request efi-2022-01-rc4-2
UEFI: * correctly handle missing TPM device * prepare for block devices for U-Boot as EFI app -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmGzHfAACgkQxIHbvCwF GsQYeA/+LFCXTVOLWtShHc71kMUdjX5tCnm3LrYEnJgc9fmo2zWD+kSbAWV7RIZG WJ1OVkLKw8+O5kvRwW/dxpZVU1fULn/vzVJxoKVM7I48XJ0JbnO9Up3GCl91i+2t h55gQ/bmt5LpOvQIAhVqQKfMhJz1fTZV77ZtKKdDKw6oeDGlL5F3WZ0RRGGhSXLY pLVKRDTm+B7HvSTth052MVjrfpfkivujDfCO+rYgw3pA4M3MdC51J4gpIWJt2SRz q/p3Fc5fU1d47KEJIfDnm6Hv76yZO3aNU6zivQoSfCqDlNYRvbNcWr4VIkvrIn4D eugMO5f0lWRqDAItq0bcslHEqLPygNJopHB190n4rPUuUfIs/Iq/x6WGBi632aYr utMWqpRrEBGMTLWburl/aZi4+Jsd/zTZsqPzDUC5Ok/KmBvrewq//lWRauRd8GXY Ka2hbMX65C9wDabOGLOTE7jDeTQqCNi4/L1Ie3yiZ/Pg83QSYpP+Jt58FyugMMuw hEEdqbH1uzVrhksaBxG1vzgkdR64i01kEt2CyOtcJnfzkkCxc2DAAFVcDq5oLbdT RCKKdP+To9/D+hvvKMQv7cqjumBUYoeFb8yoJK7UvJehrgXaazO/OSiILjTsA3Lq l9CtdorVl0FvLzgqZmoBA1H9ovkJFYswt7vZbY3VXGJuj04mvVI= =jVT6 -----END PGP SIGNATURE----- Merge tag 'efi-2022-01-rc4-2' of https://source.denx.de/u-boot/custodians/u-boot-efi Pull request efi-2022-01-rc4-2 UEFI: * correctly handle missing TPM device * prepare for block devices for U-Boot as EFI app # gpg: Signature made Fri 10 Dec 2021 04:29:20 AM EST # gpg: using RSA key 6DC4F9C71F29A6FA06B76D33C481DBBC2C051AC4 # gpg: Good signature from "Heinrich Schuchardt <xypron.glpk@gmx.de>" [unknown] # gpg: aka "[jpeg image of size 1389]" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6DC4 F9C7 1F29 A6FA 06B7 6D33 C481 DBBC 2C05 1AC4
This commit is contained in:
commit
a1c01b17c5
@ -713,8 +713,11 @@ W: https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html
|
||||
F: board/efi/efi-x86_app
|
||||
F: configs/efi-x86_app*
|
||||
F: doc/develop/uefi/u-boot_on_efi.rst
|
||||
F: drivers/block/efi-media-uclass.c
|
||||
F: drivers/block/sb_efi_media.c
|
||||
F: lib/efi/efi_app.c
|
||||
F: scripts/build-efi.sh
|
||||
F: test/dm/efi_media.c
|
||||
|
||||
EFI PAYLOAD
|
||||
M: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||
|
@ -498,6 +498,10 @@
|
||||
compatible = "sandbox,clk-ccf";
|
||||
};
|
||||
|
||||
efi-media {
|
||||
compatible = "sandbox,efi-media";
|
||||
};
|
||||
|
||||
eth@10002000 {
|
||||
compatible = "sandbox,eth";
|
||||
reg = <0x10002000 0x1000>;
|
||||
|
@ -296,8 +296,11 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
|
||||
case IF_TYPE_VIRTIO:
|
||||
puts("VirtIO");
|
||||
break;
|
||||
case IF_TYPE_EFI_MEDIA:
|
||||
puts("EFI");
|
||||
break;
|
||||
default:
|
||||
puts ("UNKNOWN");
|
||||
puts("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
printf (" device %d -- Partition Type: %s\n\n",
|
||||
|
@ -620,12 +620,12 @@ EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers.
|
||||
|
||||
A linker created list is used to keep track of the UEFI drivers. To create an
|
||||
entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying
|
||||
UCLASS_EFI as the ID of its uclass, e.g::
|
||||
UCLASS_EFI_LOADER as the ID of its uclass, e.g::
|
||||
|
||||
/* Identify as UEFI driver */
|
||||
U_BOOT_DRIVER(efi_block) = {
|
||||
.name = "EFI block driver",
|
||||
.id = UCLASS_EFI,
|
||||
.id = UCLASS_EFI_LOADER,
|
||||
.ops = &driver_ops,
|
||||
};
|
||||
|
||||
@ -651,8 +651,8 @@ UEFI block IO driver
|
||||
The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
|
||||
|
||||
When connected it creates a new U-Boot block IO device with interface type
|
||||
IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
|
||||
IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs
|
||||
the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
|
||||
software iPXE to boot from iSCSI network drives [4].
|
||||
|
||||
This driver is only available if U-Boot is configured with::
|
||||
|
@ -102,7 +102,7 @@ Manually Loading and Applying Overlays
|
||||
|
||||
::
|
||||
|
||||
=> fdtaddr $fdtaddr
|
||||
=> fdt addr $fdtaddr
|
||||
|
||||
4. Grow it enough so it can encompass all applied overlays
|
||||
|
||||
|
@ -61,6 +61,39 @@ config TPL_BLOCK_CACHE
|
||||
help
|
||||
This option enables the disk-block cache in TPL
|
||||
|
||||
config EFI_MEDIA
|
||||
bool "Support EFI media drivers"
|
||||
default y if EFI || SANDBOX
|
||||
help
|
||||
Enable this to support media devices on top of UEFI. This enables
|
||||
just the uclass so you also need a specific driver to make this do
|
||||
anything.
|
||||
|
||||
For sandbox there is a test driver.
|
||||
|
||||
if EFI_MEDIA
|
||||
|
||||
config EFI_MEDIA_SANDBOX
|
||||
bool "Sandbox EFI media driver"
|
||||
depends on SANDBOX
|
||||
default y
|
||||
help
|
||||
Enables a simple sandbox media driver, used for testing just the
|
||||
EFI_MEDIA uclass. It does not do anything useful, since sandbox does
|
||||
not actually support running on top of UEFI.
|
||||
|
||||
config EFI_MEDIA_BLK
|
||||
bool "EFI media block driver"
|
||||
depends on EFI_APP
|
||||
default y
|
||||
help
|
||||
Enables a block driver for providing access to UEFI devices. This
|
||||
allows use of block devices detected by the underlying UEFI
|
||||
implementation. With this it is possible to use filesystems on these
|
||||
devices, for example.
|
||||
|
||||
endif # EFI_MEDIA
|
||||
|
||||
config IDE
|
||||
bool "Support IDE controllers"
|
||||
select HAVE_BLOCK_DEVICE
|
||||
|
@ -14,3 +14,7 @@ obj-$(CONFIG_IDE) += ide.o
|
||||
endif
|
||||
obj-$(CONFIG_SANDBOX) += sandbox.o
|
||||
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
|
||||
|
||||
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
|
||||
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
|
||||
obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o
|
||||
|
@ -28,7 +28,8 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
|
||||
[IF_TYPE_SATA] = "sata",
|
||||
[IF_TYPE_HOST] = "host",
|
||||
[IF_TYPE_NVME] = "nvme",
|
||||
[IF_TYPE_EFI] = "efi",
|
||||
[IF_TYPE_EFI_MEDIA] = "efi",
|
||||
[IF_TYPE_EFI_LOADER] = "efiloader",
|
||||
[IF_TYPE_VIRTIO] = "virtio",
|
||||
[IF_TYPE_PVBLOCK] = "pvblock",
|
||||
};
|
||||
@ -44,7 +45,8 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
|
||||
[IF_TYPE_SATA] = UCLASS_AHCI,
|
||||
[IF_TYPE_HOST] = UCLASS_ROOT,
|
||||
[IF_TYPE_NVME] = UCLASS_NVME,
|
||||
[IF_TYPE_EFI] = UCLASS_EFI,
|
||||
[IF_TYPE_EFI_MEDIA] = UCLASS_EFI_MEDIA,
|
||||
[IF_TYPE_EFI_LOADER] = UCLASS_EFI_LOADER,
|
||||
[IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
|
||||
[IF_TYPE_PVBLOCK] = UCLASS_PVBLOCK,
|
||||
};
|
||||
|
15
drivers/block/efi-media-uclass.c
Normal file
15
drivers/block/efi-media-uclass.c
Normal file
@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Uclass for EFI media devices
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
|
||||
UCLASS_DRIVER(efi_media) = {
|
||||
.id = UCLASS_EFI_MEDIA,
|
||||
.name = "efi_media",
|
||||
.flags = DM_UC_FLAG_SEQ_ALIAS,
|
||||
};
|
115
drivers/block/efi_blk.c
Normal file
115
drivers/block/efi_blk.c
Normal file
@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Block driver for EFI devices
|
||||
* This supports a media driver of UCLASS_EFI with a child UCLASS_BLK
|
||||
* It allows block-level access to EFI devices made available via EFI boot
|
||||
* services
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <blk.h>
|
||||
#include <dm.h>
|
||||
#include <efi.h>
|
||||
#include <efi_api.h>
|
||||
|
||||
struct efi_block_plat {
|
||||
struct efi_block_io *blkio;
|
||||
};
|
||||
|
||||
/**
|
||||
* Read from block device
|
||||
*
|
||||
* @dev: device
|
||||
* @blknr: first block to be read
|
||||
* @blkcnt: number of blocks to read
|
||||
* @buffer: output buffer
|
||||
* Return: number of blocks transferred
|
||||
*/
|
||||
static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
|
||||
void *buffer)
|
||||
{
|
||||
struct efi_block_plat *plat = dev_get_plat(dev);
|
||||
struct efi_block_io *io = plat->blkio;
|
||||
efi_status_t ret;
|
||||
|
||||
log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
|
||||
(ulong)blkcnt);
|
||||
ret = io->read_blocks(io, io->media->media_id, blknr,
|
||||
blkcnt * io->media->block_size, buffer);
|
||||
log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
|
||||
ret & ~EFI_ERROR_MASK);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return blkcnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to block device
|
||||
*
|
||||
* @dev: device
|
||||
* @blknr: first block to be write
|
||||
* @blkcnt: number of blocks to write
|
||||
* @buffer: input buffer
|
||||
* Return: number of blocks transferred
|
||||
*/
|
||||
static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
|
||||
const void *buffer)
|
||||
{
|
||||
struct efi_block_plat *plat = dev_get_plat(dev);
|
||||
struct efi_block_io *io = plat->blkio;
|
||||
efi_status_t ret;
|
||||
|
||||
log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
|
||||
(ulong)blkcnt);
|
||||
ret = io->write_blocks(io, io->media->media_id, blknr,
|
||||
blkcnt * io->media->block_size, (void *)buffer);
|
||||
log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
|
||||
ret & ~EFI_ERROR_MASK);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return blkcnt;
|
||||
}
|
||||
|
||||
/* Block device driver operators */
|
||||
static const struct blk_ops efi_blk_ops = {
|
||||
.read = efi_bl_read,
|
||||
.write = efi_bl_write,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(efi_block) = {
|
||||
.name = "efi_block",
|
||||
.id = UCLASS_BLK,
|
||||
.ops = &efi_blk_ops,
|
||||
.plat_auto = sizeof(struct efi_block_plat),
|
||||
};
|
||||
|
||||
static int efi_media_bind(struct udevice *dev)
|
||||
{
|
||||
struct efi_media_plat *plat = dev_get_plat(dev);
|
||||
struct efi_block_plat *blk_plat;
|
||||
struct udevice *blk;
|
||||
int ret;
|
||||
|
||||
ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA,
|
||||
dev_seq(dev), plat->blkio->media->block_size,
|
||||
plat->blkio->media->last_block, &blk);
|
||||
if (ret) {
|
||||
debug("Cannot create block device\n");
|
||||
return ret;
|
||||
}
|
||||
blk_plat = dev_get_plat(blk);
|
||||
blk_plat->blkio = plat->blkio;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(efi_media) = {
|
||||
.name = "efi_media",
|
||||
.id = UCLASS_EFI_MEDIA,
|
||||
.bind = efi_media_bind,
|
||||
.plat_auto = sizeof(struct efi_media_plat),
|
||||
};
|
20
drivers/block/sb_efi_media.c
Normal file
20
drivers/block/sb_efi_media.c
Normal file
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* EFI_MEDIA driver for sandbox
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
|
||||
static const struct udevice_id sandbox_efi_media_ids[] = {
|
||||
{ .compatible = "sandbox,efi-media" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_efi_media) = {
|
||||
.name = "sandbox_efi_media",
|
||||
.id = UCLASS_EFI_MEDIA,
|
||||
.of_match = sandbox_efi_media_ids,
|
||||
};
|
@ -34,9 +34,10 @@ enum if_type {
|
||||
IF_TYPE_SATA,
|
||||
IF_TYPE_HOST,
|
||||
IF_TYPE_NVME,
|
||||
IF_TYPE_EFI,
|
||||
IF_TYPE_EFI_LOADER,
|
||||
IF_TYPE_PVBLOCK,
|
||||
IF_TYPE_VIRTIO,
|
||||
IF_TYPE_EFI_MEDIA,
|
||||
|
||||
IF_TYPE_COUNT, /* Number of interface types */
|
||||
};
|
||||
|
@ -48,7 +48,8 @@ enum uclass_id {
|
||||
UCLASS_DMA, /* Direct Memory Access */
|
||||
UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */
|
||||
UCLASS_ECDSA, /* Elliptic curve cryptographic device */
|
||||
UCLASS_EFI, /* EFI managed devices */
|
||||
UCLASS_EFI_LOADER, /* Devices created by UEFI applications */
|
||||
UCLASS_EFI_MEDIA, /* Devices provided by UEFI firmware */
|
||||
UCLASS_ETH, /* Ethernet device */
|
||||
UCLASS_ETH_PHY, /* Ethernet PHY device */
|
||||
UCLASS_FIRMWARE, /* Firmware */
|
||||
|
@ -414,6 +414,17 @@ struct efi_priv {
|
||||
void *next_hdr;
|
||||
};
|
||||
|
||||
/*
|
||||
* EFI attributes of the udevice handled by efi_media driver
|
||||
*
|
||||
* @handle: handle of the controller on which this driver is installed
|
||||
* @blkio: block io protocol proxied by this driver
|
||||
*/
|
||||
struct efi_media_plat {
|
||||
efi_handle_t handle;
|
||||
struct efi_block_io *blkio;
|
||||
};
|
||||
|
||||
/* Base address of the EFI image */
|
||||
extern char image_base[];
|
||||
|
||||
|
@ -525,6 +525,8 @@ efi_status_t efi_disk_register(void);
|
||||
efi_status_t efi_rng_register(void);
|
||||
/* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
|
||||
efi_status_t efi_tcg2_register(void);
|
||||
/* Called by efi_init_obj_list() to do initial measurement */
|
||||
efi_status_t efi_tcg2_do_initial_measurement(void);
|
||||
/* measure the pe-coff image, extend PCR and add Event Log */
|
||||
efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
||||
struct efi_loaded_image_obj *handle,
|
||||
|
@ -147,7 +147,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
|
||||
if (!obj)
|
||||
return -ENOENT;
|
||||
|
||||
devnum = blk_find_max_devnum(IF_TYPE_EFI);
|
||||
devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER);
|
||||
if (devnum == -ENODEV)
|
||||
devnum = 0;
|
||||
else if (devnum < 0)
|
||||
@ -159,8 +159,8 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
|
||||
sprintf(name, "efiblk#%d", devnum);
|
||||
|
||||
/* Create driver model udevice for the EFI block io device */
|
||||
ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum,
|
||||
io->media->block_size,
|
||||
ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER,
|
||||
devnum, io->media->block_size,
|
||||
(lbaint_t)io->media->last_block, &bdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -209,6 +209,6 @@ static const struct efi_driver_ops driver_ops = {
|
||||
/* Identify as EFI driver */
|
||||
U_BOOT_DRIVER(efi_block) = {
|
||||
.name = "EFI block driver",
|
||||
.id = UCLASS_EFI,
|
||||
.id = UCLASS_EFI_LOADER,
|
||||
.ops = &driver_ops,
|
||||
};
|
||||
|
@ -308,7 +308,7 @@ efi_status_t efi_driver_init(void)
|
||||
log_debug("Initializing EFI driver framework\n");
|
||||
for (drv = ll_entry_start(struct driver, driver);
|
||||
drv < ll_entry_end(struct driver, driver); ++drv) {
|
||||
if (drv->id == UCLASS_EFI) {
|
||||
if (drv->id == UCLASS_EFI_LOADER) {
|
||||
ret = efi_add_driver(drv);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_err("Failed to add EFI driver %s\n",
|
||||
@ -328,7 +328,7 @@ efi_status_t efi_driver_init(void)
|
||||
*/
|
||||
static int efi_uc_init(struct uclass *class)
|
||||
{
|
||||
log_debug("Initializing UCLASS_EFI\n");
|
||||
log_debug("Initializing UCLASS_EFI_LOADER\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -340,13 +340,13 @@ static int efi_uc_init(struct uclass *class)
|
||||
*/
|
||||
static int efi_uc_destroy(struct uclass *class)
|
||||
{
|
||||
log_debug("Destroying UCLASS_EFI\n");
|
||||
log_debug("Destroying UCLASS_EFI_LOADER\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(efi) = {
|
||||
.name = "efi",
|
||||
.id = UCLASS_EFI,
|
||||
.id = UCLASS_EFI_LOADER,
|
||||
.init = efi_uc_init,
|
||||
.destroy = efi_uc_destroy,
|
||||
};
|
||||
|
@ -308,6 +308,8 @@ config EFI_TCG2_PROTOCOL
|
||||
bool "EFI_TCG2_PROTOCOL support"
|
||||
default y
|
||||
depends on TPM_V2
|
||||
# Sandbox TPM currently fails on GetCapabilities needed for TCG2
|
||||
depends on !SANDBOX
|
||||
select SHA1
|
||||
select SHA256
|
||||
select SHA384
|
||||
|
@ -3016,9 +3016,12 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
|
||||
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
|
||||
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
|
||||
ret = efi_tcg2_measure_efi_app_invocation(image_obj);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
log_warning("tcg2 measurement fails(0x%lx)\n",
|
||||
ret);
|
||||
if (ret == EFI_SECURITY_VIOLATION) {
|
||||
/*
|
||||
* TCG2 Protocol is installed but no TPM device found,
|
||||
* this is not expected.
|
||||
*/
|
||||
return EFI_EXIT(EFI_SECURITY_VIOLATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -934,9 +934,16 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
|
||||
|
||||
#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
|
||||
/* Measure an PE/COFF image */
|
||||
if (tcg2_measure_pe_image(efi, efi_size, handle,
|
||||
loaded_image_info))
|
||||
log_err("PE image measurement failed\n");
|
||||
ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info);
|
||||
if (ret == EFI_SECURITY_VIOLATION) {
|
||||
/*
|
||||
* TCG2 Protocol is installed but no TPM device found,
|
||||
* this is not expected.
|
||||
*/
|
||||
log_err("PE image measurement failed, no tpm device found\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Copy PE headers */
|
||||
|
@ -241,6 +241,10 @@ efi_status_t efi_init_obj_list(void)
|
||||
ret = efi_tcg2_register();
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret = efi_tcg2_do_initial_measurement();
|
||||
if (ret == EFI_SECURITY_VIOLATION)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Secure boot */
|
||||
|
@ -153,6 +153,15 @@ static u16 alg_to_len(u16 hash_alg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_tcg2_protocol_installed(void)
|
||||
{
|
||||
struct efi_handler *handler;
|
||||
efi_status_t ret;
|
||||
|
||||
ret = efi_search_protocol(efi_root, &efi_guid_tcg2_protocol, &handler);
|
||||
return ret == EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
|
||||
{
|
||||
u32 len;
|
||||
@ -963,9 +972,12 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
||||
IMAGE_NT_HEADERS32 *nt;
|
||||
struct efi_handler *handler;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
|
||||
switch (handle->image_type) {
|
||||
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
||||
@ -1664,6 +1676,14 @@ void tcg2_uninit(void)
|
||||
event_log.buffer = NULL;
|
||||
efi_free_pool(event_log.final_buffer);
|
||||
event_log.final_buffer = NULL;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return;
|
||||
|
||||
ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol,
|
||||
(void *)&efi_tcg2_protocol);
|
||||
if (ret != EFI_SUCCESS)
|
||||
log_err("Failed to remove EFI TCG2 protocol\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2172,12 +2192,15 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
|
||||
u32 event = 0;
|
||||
struct smbios_entry *entry;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (tcg2_efi_app_invoked)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
|
||||
ret = tcg2_measure_boot_variable(dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
@ -2222,6 +2245,9 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void)
|
||||
efi_status_t ret;
|
||||
struct udevice *dev;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return ret;
|
||||
@ -2247,6 +2273,12 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
|
||||
EFI_ENTRY("%p, %p", event, context);
|
||||
|
||||
event_log.ebs_called = true;
|
||||
|
||||
if (!is_tcg2_protocol_installed()) {
|
||||
ret = EFI_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
@ -2276,6 +2308,9 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
|
||||
struct udevice *dev;
|
||||
efi_status_t ret;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
@ -2345,12 +2380,37 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_tcg2_do_initial_measurement() - do initial measurement
|
||||
*
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_tcg2_do_initial_measurement(void)
|
||||
{
|
||||
efi_status_t ret;
|
||||
struct udevice *dev;
|
||||
|
||||
if (!is_tcg2_protocol_installed())
|
||||
return EFI_SUCCESS;
|
||||
|
||||
ret = platform_get_tpm2_device(&dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
|
||||
ret = tcg2_measure_secure_boot_variable(dev);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_tcg2_register() - register EFI_TCG2_PROTOCOL
|
||||
*
|
||||
* If a TPM2 device is available, the TPM TCG2 Protocol is registered
|
||||
*
|
||||
* Return: An error status is only returned if adding the protocol fails.
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_tcg2_register(void)
|
||||
{
|
||||
@ -2373,8 +2433,10 @@ efi_status_t efi_tcg2_register(void)
|
||||
}
|
||||
|
||||
ret = efi_init_event_log();
|
||||
if (ret != EFI_SUCCESS)
|
||||
if (ret != EFI_SUCCESS) {
|
||||
tcg2_uninit();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
|
||||
(void *)&efi_tcg2_protocol);
|
||||
@ -2391,24 +2453,9 @@ efi_status_t efi_tcg2_register(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = tcg2_measure_secure_boot_variable(dev);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
tcg2_uninit();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
log_err("Cannot install EFI_TCG2_PROTOCOL\n");
|
||||
/*
|
||||
* Return EFI_SUCCESS and don't stop the EFI subsystem.
|
||||
* That's done for 2 reasons
|
||||
* - If the protocol is not installed the PCRs won't be extended. So
|
||||
* someone later in the boot flow will notice that and take the
|
||||
* necessary actions.
|
||||
* - The TPM sandbox is limited and we won't be able to run any efi
|
||||
* related tests with TCG2 enabled
|
||||
*/
|
||||
return EFI_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ obj-$(CONFIG_DMA) += dma.o
|
||||
obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
|
||||
obj-$(CONFIG_DM_DSA) += dsa.o
|
||||
obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
|
||||
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o
|
||||
obj-$(CONFIG_DM_ETH) += eth.o
|
||||
ifneq ($(CONFIG_EFI_PARTITION),)
|
||||
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
|
||||
|
24
test/dm/efi_media.c
Normal file
24
test/dm/efi_media.c
Normal file
@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Test for EFI_MEDIA uclass
|
||||
*
|
||||
* Copyright 2021 Google LLC
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/test.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
/* Test that we can use the EFI_MEDIA uclass */
|
||||
static int dm_test_efi_media(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
||||
ut_assertok(uclass_first_device_err(UCLASS_EFI_MEDIA, &dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_efi_media, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
Loading…
Reference in New Issue
Block a user