aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-12-10 07:58:43 -0500
committerTom Rini <trini@konsulko.com>2021-12-10 07:58:43 -0500
commita1c01b17c59ec03c678073e145fbd094c7606dc8 (patch)
tree6b0c87c85a818d8955ca2e199bdb52e219e578d0
parent1530ad5becf330c6094e995e340d920df2b43699 (diff)
parentd8063dc373eb5ed5b4a31fdd3eecd32cba592696 (diff)
downloadu-boot-WIP/10Dec2021.zip
u-boot-WIP/10Dec2021.tar.gz
u-boot-WIP/10Dec2021.tar.bz2
Merge tag 'efi-2022-01-rc4-2' of https://source.denx.de/u-boot/custodians/u-boot-efiWIP/10Dec2021
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
-rw-r--r--MAINTAINERS3
-rw-r--r--arch/sandbox/dts/test.dts4
-rw-r--r--disk/part.c5
-rw-r--r--doc/develop/uefi/uefi.rst8
-rw-r--r--doc/usage/fdt_overlays.rst2
-rw-r--r--drivers/block/Kconfig33
-rw-r--r--drivers/block/Makefile4
-rw-r--r--drivers/block/blk-uclass.c6
-rw-r--r--drivers/block/efi-media-uclass.c15
-rw-r--r--drivers/block/efi_blk.c115
-rw-r--r--drivers/block/sb_efi_media.c20
-rw-r--r--include/blk.h3
-rw-r--r--include/dm/uclass-id.h3
-rw-r--r--include/efi.h11
-rw-r--r--include/efi_loader.h2
-rw-r--r--lib/efi_driver/efi_block_device.c8
-rw-r--r--lib/efi_driver/efi_uclass.c8
-rw-r--r--lib/efi_loader/Kconfig2
-rw-r--r--lib/efi_loader/efi_boottime.c9
-rw-r--r--lib/efi_loader/efi_image_loader.c13
-rw-r--r--lib/efi_loader/efi_setup.c4
-rw-r--r--lib/efi_loader/efi_tcg2.c87
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/efi_media.c24
24 files changed, 346 insertions, 44 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index e718ad2..90666ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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>
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 8cd688e..2cea4a4 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -498,6 +498,10 @@
compatible = "sandbox,clk-ccf";
};
+ efi-media {
+ compatible = "sandbox,efi-media";
+ };
+
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x10002000 0x1000>;
diff --git a/disk/part.c b/disk/part.c
index fe1ebd4..e857a9f 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -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",
diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst
index f17138f..a3e2656 100644
--- a/doc/develop/uefi/uefi.rst
+++ b/doc/develop/uefi/uefi.rst
@@ -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::
diff --git a/doc/usage/fdt_overlays.rst b/doc/usage/fdt_overlays.rst
index ea39713..7f113ed 100644
--- a/doc/usage/fdt_overlays.rst
+++ b/doc/usage/fdt_overlays.rst
@@ -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
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 56a4eec..8235430 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -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
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 94ab5c6..b221a7c 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -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
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 83682dc..4ae8af6 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -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,
};
diff --git a/drivers/block/efi-media-uclass.c b/drivers/block/efi-media-uclass.c
new file mode 100644
index 0000000..e012f6f
--- /dev/null
+++ b/drivers/block/efi-media-uclass.c
@@ -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,
+};
diff --git a/drivers/block/efi_blk.c b/drivers/block/efi_blk.c
new file mode 100644
index 0000000..9d25ecb
--- /dev/null
+++ b/drivers/block/efi_blk.c
@@ -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),
+};
diff --git a/drivers/block/sb_efi_media.c b/drivers/block/sb_efi_media.c
new file mode 100644
index 0000000..52af155
--- /dev/null
+++ b/drivers/block/sb_efi_media.c
@@ -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,
+};
diff --git a/include/blk.h b/include/blk.h
index f0cc7ca..dde2173 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -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 */
};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index fd139b9..0e26e1d 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -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 */
diff --git a/include/efi.h b/include/efi.h
index b583542..0ec5913 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -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[];
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 67c40ca..f4860e8 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -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,
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
index 0937e35..04cb3ef 100644
--- a/lib/efi_driver/efi_block_device.c
+++ b/lib/efi_driver/efi_block_device.c
@@ -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,
};
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c
index 382c2b4..b01ce89 100644
--- a/lib/efi_driver/efi_uclass.c
+++ b/lib/efi_driver/efi_uclass.c
@@ -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,
};
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 700dc83..24f9a2b 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -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
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 8492b73..20b6969 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -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);
}
}
}
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index eb95580..773bd06 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -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 */
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 1aba71c..49172e3 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -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 */
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 5f71b18..0ae07ef 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -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;
@@ -2346,11 +2381,36 @@ error:
}
/**
+ * 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;
}
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 548649f..d46552f 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -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
diff --git a/test/dm/efi_media.c b/test/dm/efi_media.c
new file mode 100644
index 0000000..e343a0e
--- /dev/null
+++ b/test/dm/efi_media.c
@@ -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);