
Hi Eddie,
On Wed, 22 Feb 2023 at 11:02, Eddie James eajames@linux.ibm.com wrote:
Add a configuration option to measure the boot through the bootm function. Add the measurement state to the booti and bootz paths as well.
Signed-off-by: Eddie James eajames@linux.ibm.com
boot/Kconfig | 23 ++++++++++++++++ boot/bootm.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd/booti.c | 1 + cmd/bootm.c | 2 ++ cmd/bootz.c | 1 + include/bootm.h | 2 ++ include/image.h | 1 + 7 files changed, 100 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
diff --git a/boot/Kconfig b/boot/Kconfig index 5f491625c8..d0d5e5794c 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -629,6 +629,29 @@ config LEGACY_IMAGE_FORMAT loaded. If a board needs the legacy image format support in this case, enable it here.
+config MEASURED_BOOT
bool "Measure boot images and configuration to TPM and event log"
depends on HASH && TPM_V2
help
This option enables measurement of the boot process. Measurement
involves creating cryptographic hashes of the binary images that
are booting and storing them in the TPM. In addition, a log of
these hashes is stored in memory for the OS to verify the booted
images and configuration. Enable this if the OS has configured
some memory area for the event log and you intend to use some
attestation tools on your system.
+if MEASURED_BOOT
config MEASURE_DEVICETREE
bool "Measure the devicetree image"
default y if MEASURED_BOOT
help
On some platforms, the devicetree is not static as it may contain
random MAC addresses or other such data that changes each boot.
Therefore, it should not be measured into the TPM. In that case,
disable the measurement here.
+endif # MEASURED_BOOT
config SUPPORT_RAW_INITRD bool "Enable raw initrd images" help diff --git a/boot/bootm.c b/boot/bootm.c index 2eec60ec7b..10b4848c7e 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -22,6 +22,7 @@ #include <asm/global_data.h> #include <asm/io.h> #include <linux/sizes.h> +#include <tpm-v2.h> #if defined(CONFIG_CMD_USB) #include <usb.h> #endif @@ -659,6 +660,72 @@ int bootm_process_cmdline_env(int flags) return 0; }
+int bootm_measure(struct bootm_headers *images) +{
int ret = 0;
/* Skip measurement if EFI is going to do it */
if (images->os.os == IH_OS_EFI &&
IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) &&
IS_ENABLED(CONFIG_BOOTM_EFI))
return ret;
if (IS_ENABLED(CONFIG_MEASURED_BOOT)) {
struct tcg2_event_log elog;
struct udevice *dev;
void *initrd_buf;
void *image_buf;
const char *s;
u32 rd_len;
ret = tcg2_measurement_init(&dev, &elog);
if (ret)
return ret;
image_buf = map_sysmem(images->os.image_start,
images->os.image_len);
ret = tcg2_measure_data(dev, &elog, 8, images->os.image_len,
image_buf, EV_COMPACT_HASH,
strlen("linux") + 1, (u8 *)"linux");
if (ret)
goto unmap_image;
rd_len = images->rd_end - images->rd_start;
initrd_buf = map_sysmem(images->rd_start, rd_len);
ret = tcg2_measure_data(dev, &elog, 9, rd_len, initrd_buf,
EV_COMPACT_HASH, strlen("initrd") + 1,
(u8 *)"initrd");
if (ret)
goto unmap_initrd;
if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) {
ret = tcg2_measure_data(dev, &elog, 0, images->ft_len,
(u8 *)images->ft_addr,
EV_TABLE_OF_DEVICES,
strlen("dts") + 1,
(u8 *)"dts");
if (ret)
goto unmap_initrd;
}
s = env_get("bootargs");
if (!s)
s = "";
ret = tcg2_measure_data(dev, &elog, 1, strlen(s) + 1, (u8 *)s,
EV_PLATFORM_CONFIG_FLAGS,
strlen(s) + 1, (u8 *)s);
+unmap_initrd:
unmap_sysmem(initrd_buf);
+unmap_image:
unmap_sysmem(image_buf);
tcg2_measurement_term(dev, &elog, ret != 0);
}
return ret;
+}
/**
- Execute selected states of the bootm command.
@@ -710,6 +777,9 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, if (!ret && (states & BOOTM_STATE_FINDOTHER)) ret = bootm_find_other(cmdtp, flag, argc, argv);
if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && (states & BOOTM_STATE_MEASURE))
line length?
bootm_measure(images);
/* Load the OS */ if (!ret && (states & BOOTM_STATE_LOADOS)) { iflag = bootm_disable_interrupts();
diff --git a/cmd/booti.c b/cmd/booti.c index 6ac39193db..659bb10549 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -127,6 +127,7 @@ int do_booti(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH BOOTM_STATE_RAMDISK | #endif
BOOTM_STATE_MEASURE | BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1);
diff --git a/cmd/bootm.c b/cmd/bootm.c index 37c2af96e0..0c4a713e02 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -161,6 +161,8 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) BOOTM_STATE_OS_GO; if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH)) states |= BOOTM_STATE_RAMDISK;
if (IS_ENABLED(CONFIG_MEASURED_BOOT))
states |= BOOTM_STATE_MEASURE; if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS)) states |= BOOTM_STATE_OS_CMDLINE; ret = do_bootm_states(cmdtp, flag, argc, argv, states, &images, 1);
diff --git a/cmd/bootz.c b/cmd/bootz.c index f1423573d2..87922bfc3c 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -81,6 +81,7 @@ int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH BOOTM_STATE_RAMDISK | #endif
BOOTM_STATE_MEASURE | BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO, &images, 1);
diff --git a/include/bootm.h b/include/bootm.h index 044a4797ed..06d8b1acd8 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -55,6 +55,8 @@ ulong bootm_disable_interrupts(void); int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size);
+int bootm_measure(struct bootm_headers *images);
please add a full comment for this, including what it actually does / 'measures' and what 'measure' means.
int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], int states, struct bootm_headers *images, int boot_progress); diff --git a/include/image.h b/include/image.h index 7717a4c13d..f7414b5338 100644 --- a/include/image.h +++ b/include/image.h @@ -407,6 +407,7 @@ struct bootm_headers { #define BOOTM_STATE_OS_FAKE_GO 0x00000200 /* 'Almost' run the OS */ #define BOOTM_STATE_OS_GO 0x00000400 #define BOOTM_STATE_PRE_LOAD 0x00000800 +#define BOOTM_STATE_MEASURE 0x00001000 int state;
#if defined(CONFIG_LMB) && !defined(USE_HOSTCC)
2.31.1
Regards, Simon