From patchwork Wed May 10 07:43:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 680508 Delivered-To: patch@linaro.org Received: by 2002:a5d:4a41:0:0:0:0:0 with SMTP id v1csp2697174wrs; Wed, 10 May 2023 00:45:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7phPZS3uCpYgXg80oFrv8/q5vW6gR1sRd94yKXTHD6zddcG7hr+vj9oHEsufKcOjtChRQa X-Received: by 2002:a05:6a00:2309:b0:63d:254a:3902 with SMTP id h9-20020a056a00230900b0063d254a3902mr23562473pfh.12.1683704705715; Wed, 10 May 2023 00:45:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683704705; cv=none; d=google.com; s=arc-20160816; b=DjiA6iQzPlor2wKx6E3SiGkkxFLTjhUmAhRssxqjEQSiTfoEBvuOlRLCsmZjaG4YCJ czKCaxJZEH35UuE2lWyZ00IfOQSOboNwY9Ws7OrBZfMO5F25PkxFIv1lrYzs3XigKJ0X wpWtHJ8+mqd+oPzY6yAPUgOFrRDfFBDvn3MmTF3eJ/G+a5H+7EcLvVQfSzH2w+/i83gb hlfGrWzo1uo6CshgftGeRQ/9BbhbUCJ/daQGrKY+p840O3rzHMC9O32rhOzhzkTGFOlc 0pVhr8x7CsN3IUaehA9f+uuiGsDOwOKBxCIdEVCyZCvcNtvaZhiMzB+LYfVa/liSGLb/ 0X7A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=qK5yYBi7yGSbRUbcmTVJMv5IL1Cc9bttluP7oKipluY=; b=HaQ/9ZnbjisWH+5KIjMJ+ZJRksr/uO7JRN47X1glv9ugSYX0MJaBxLxMgGYV1nxlff G3bEmTBWEIhVaVTwA+hPfD547FacDHIAO7gBgOsOwDk8YSsWeY4t9CzDFx06cNnhC2ll yu76Ioi4KELqJCRAVa+uK5suxWjQ0HZOwWDNoW7/4S7PLsovOUnziNbDCGoDnZ3jGAvC S6WczXKJk0wFK6tVkl72VWzEjvMHcT/3kOnXaci8gOD9qzSJjFRruRFYv5xrA9i9Fc1f thgIawSZD5vBCS36SQhWYMdbLWR+QhVO2p9va05UVrohDIEihMtBhZESLHaB82Lx5ubm bQfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sol3Umjz; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id g9-20020a63fa49000000b0051bb415165dsi3473833pgk.194.2023.05.10.00.45.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 May 2023 00:45:05 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=sol3Umjz; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B146E8606E; Wed, 10 May 2023 09:44:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="sol3Umjz"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7C48A86037; Wed, 10 May 2023 09:44:33 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id E3F1986055 for ; Wed, 10 May 2023 09:44:27 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-3f42c865535so15707635e9.1 for ; Wed, 10 May 2023 00:44:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1683704667; x=1686296667; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qK5yYBi7yGSbRUbcmTVJMv5IL1Cc9bttluP7oKipluY=; b=sol3UmjzsLK4zFFmzK3ocfbBjw8Ki0q719Wl8bakBLJMOvpZ3mGrrrMpj3bE7WMdY5 kLH00clUwEbKELBZNIwaQXWYdsgGncyiNxfgNenUmGWW5I8ELzSuxKJLTf+rQcB2jrIC lHk3/5/4etMQdl86wuTJW6tEAUONCs4zovnAie8Xagvt54IqkvbnAd/jrdnyMlZprMyw B0c06vi5O3vUnd3qa5EbduhrYquDaIT1p6gL9pGQV1e2pFB3SPh/Yd+zs3iJDmmWSrkz fH17ipKN6/ADh7pgBiXt3Qbgy9QAhQO+p9ZQ02KACpTIVbeFGGTiKa5RWzaVj42Lxiwg w9Qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683704667; x=1686296667; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qK5yYBi7yGSbRUbcmTVJMv5IL1Cc9bttluP7oKipluY=; b=Q/8rgcRs/FivvMlMfO3tMRZ6BXBUsaAAHnshiQxyqzTLFxoDpzpx5p7ECjYvneRQ7V spxZOcSRj54R1Fuu9ptBeJjIR806lVHcFAz2XjP92XbSHQtEd3Ofzinnfsj5IP+nd09z LzgDd2l5zVbMgmRNY1mRlkRRp5cKfkFp7XULRU9v1PxVnJv/N/e/XNdqeENUrfAyxUL3 xfK9BBO+FbsL8muA4a5ASqvH0r9XJ3an7Q0Scc2wiZz6Q2XngsieVh2PKCe0jReAbkoq 301v4zDJxasmB90tzEtPJ/SeYxIFC/T9ctG4c6pAvkIVtp+m0/JzSZwIGgfrvCeAuxX4 jBRA== X-Gm-Message-State: AC+VfDxhWTbakKF0i9H00AOFOLOtX00vs96x371giC8LsLvH10swfdkZ 93KpJEeZgdxwVO3RCkiMhors4cvQjFjzlShAbJGnvg== X-Received: by 2002:a05:600c:209:b0:3f1:72ec:4015 with SMTP id 9-20020a05600c020900b003f172ec4015mr11360976wmi.13.1683704667220; Wed, 10 May 2023 00:44:27 -0700 (PDT) Received: from localhost.localdomain (ppp176092130041.access.hol.gr. [176.92.130.41]) by smtp.gmail.com with ESMTPSA id p20-20020a1c7414000000b003f435652aaesm2022446wmc.11.2023.05.10.00.44.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 May 2023 00:44:26 -0700 (PDT) From: Ilias Apalodimas To: u-boot@lists.denx.de Cc: Eddie James , Simon Glass , Ilias Apalodimas , Heinrich Schuchardt , Michal Suchanek , Robert Marko , Dzmitry Sankouski , Rasmus Villemoes , Sean Anderson , Nikhil M Jain , Abdellatif El Khlifi , Andrew Davis , Daniel Golle , Safae Ouajih , Mattijs Korpershoek , =?utf-8?q?Pali_Roh=C3=A1r?= , Sughosh Ganu , Roger Knecht , Steven Lawrance , Rui Miguel Silva , Marek Vasut , Stephen Carlson , Linus Walleij , Kautuk Consul , Leo Yu-Chi Liang , Brandon Maier , Patrick Delaunay Subject: [PATCH 4/9] bootm: Support boot measurement Date: Wed, 10 May 2023 10:43:52 +0300 Message-Id: <20230510074359.2837818-4-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230510074359.2837818-1-ilias.apalodimas@linaro.org> References: <20230510074359.2837818-1-ilias.apalodimas@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Eddie James 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 Reviewed-by: Simon Glass --- boot/Kconfig | 32 +++++++++++++++++++++ boot/bootm.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd/booti.c | 1 + cmd/bootm.c | 2 ++ cmd/bootz.c | 1 + include/bootm.h | 11 ++++++++ include/image.h | 1 + 7 files changed, 122 insertions(+) diff --git a/boot/Kconfig b/boot/Kconfig index 8c27f52ec3ed..c05fbb44ff4f 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -658,6 +658,38 @@ 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. + + config MEASURE_IGNORE_LOG + bool "Ignore the existing event log" + default n + help + On platforms that use an event log memory region that persists + through system resets and are the first stage bootloader, then + this option should be enabled to ignore any existing data in the + event log memory region. +endif # MEASURED_BOOT + config SUPPORT_RAW_INITRD bool "Enable raw initrd images" help diff --git a/boot/bootm.c b/boot/bootm.c index 4144ff3b0318..d6d405a1d8ea 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -22,6 +22,7 @@ #include #include #include +#include #if defined(CONFIG_CMD_USB) #include #endif @@ -672,6 +673,75 @@ 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; + bool ign; + + elog.log_size = 0; + ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG); + ret = tcg2_measurement_init(&dev, &elog, ign); + 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. * @@ -723,6 +793,10 @@ 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)) + 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 6ac39193db80..659bb1054988 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 37c2af96e087..0c4a713e02be 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 f1423573d23d..87922bfc3c6f 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 044a4797ed36..76e8e38c82fe 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -55,6 +55,17 @@ ulong bootm_disable_interrupts(void); int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size); +/* + * Measure the boot images. Measurement is the process of hashing some binary + * data and storing it into secure memory, i.e. TPM PCRs. In addition, each + * measurement is logged into the platform event log such that the operating + * system can access it and perform attestation of the boot. + * + * @images: The structure containing the various images to boot (linux, + * initrd, dts, etc.) + */ +int bootm_measure(struct bootm_headers *images); + 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 456197d6fdae..07893942efa5 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)