From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7DCE8C05027 for ; Fri, 17 Feb 2023 17:18:49 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9C9D385A67; Fri, 17 Feb 2023 18:18:47 +0100 (CET) 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="L9/QmFXL"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 08D0D85AAF; Fri, 17 Feb 2023 18:18:46 +0100 (CET) Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) (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 EAA328574F for ; Fri, 17 Feb 2023 18:18:42 +0100 (CET) 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-wr1-x432.google.com with SMTP id e10so1698071wrg.4 for ; Fri, 17 Feb 2023 09:18:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=mxCtEXFJHUcfLOBEJ73tQjuPd+Uk9BC3KoIfg7+Yn50=; b=L9/QmFXL2mF/O+7n5NgEvqs1WbJ6U90GP7hwF6EYqBaz7JMlUsudtTHaxlfJ6l2sgg L1CrNL5RzNUF3/NGC4FYYq3q3eAw26yd1QIOaNHoEE/pShqSXCpsynvzmZWGXHWGI0e3 FlG9gOQ1ykAG5JUa/e1gW5qEjsVHF92ueal0LEpN23TC5EPvrP5ZdydM8SMizkDeAlQ8 fXFl/8npgDNYNw3lTqUuZBojEIzWraCz+1OZSsnI/8DByP51iS8Ym2hZgfC2wMzPM2MD 9gw6Tzvt2gSB8BCxpFP1+lc5gmgvxmnDuHnICfSAr8bJYFOAF/cB+aqicQP57mob2UR/ dcyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=mxCtEXFJHUcfLOBEJ73tQjuPd+Uk9BC3KoIfg7+Yn50=; b=JqLuGNu4TQdAgkmr+0jA7khwxK7X5i2crRVmCJ3izaijCqgGL50grPH9VYORyCC9+c HN3h1WRsKmileiOTE9j2q1GoR33ztkYI/DLQf7u42R17Bqxp0V42l85iefDOFwweYRqZ ZOWGVmV5o5EKhoWGmS/iLOfyxFSZbiJCcePfrPpTLtCcKbW1UeaMHTOj2az30LhT/2Cd zPKck/RbZX6keK9b0EOLmVx12hro+xIgtOFM/5dmakcXfblR9OhvyDhgs9ZCFZ1maAe7 ml+gjfIRimrl5lUvgdU07Xbyx7v5+tKM7G2g8wl1/KbSYz4sTANce2DNFaEhh09nYq2c h1kA== X-Gm-Message-State: AO0yUKXL1nk3QOlzZq1D9+o+i55As0pDTGJ2wvy1vMffOYVuz8//ruwT iYw82dPVgqwFleL0SA2UCtMFcg== X-Google-Smtp-Source: AK7set81XniqjekJg0eBUmOIW6ZeR5ruIb13xYH+eHtiQyLUVc9K848IyKYeH6wT0tYv0pIfkkgnqg== X-Received: by 2002:a5d:5182:0:b0:2c5:499e:df69 with SMTP id k2-20020a5d5182000000b002c5499edf69mr328793wrv.68.1676654322360; Fri, 17 Feb 2023 09:18:42 -0800 (PST) Received: from hera (ppp176092130041.access.hol.gr. [176.92.130.41]) by smtp.gmail.com with ESMTPSA id s17-20020a5d4251000000b002c6e8cb612fsm1602869wrr.92.2023.02.17.09.18.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Feb 2023 09:18:42 -0800 (PST) Date: Fri, 17 Feb 2023 19:18:39 +0200 From: Ilias Apalodimas To: Etienne Carriere Cc: u-boot@lists.denx.de, Heinrich Schuchardt , Simon Glass Subject: Re: [PATCH v2] efi_loader: Measure the loaded DTB Message-ID: References: <20230216162948.2343115-1-etienne.carriere@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20230216162948.2343115-1-etienne.carriere@linaro.org> 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.6 at phobos.denx.de X-Virus-Status: Clean Hi Etienne On Thu, Feb 16, 2023 at 05:29:48PM +0100, Etienne Carriere wrote: > Measures the DTB passed to the EFI application upon new boolean config > switch CONFIG_EFI_TCG2_PROTOCOL_MEASURE_DTB. For platforms where the > content of the DTB passed to the OS can change across reboots, there is > not point measuring it hence the config switch to allow platform to not > embed this feature. > > Co-developed-by: Ilias Apalodimas > Signed-off-by: Ilias Apalodimas > Signed-off-by: Etienne Carriere > --- > Changes since v1 > - Moved measurement to after DTB tweaks in efi_install_fdt() and change > its measure to hash only populated areas in the DTB (header, structs, > strings and reserved memory maps). efi_tcg2_measure_dtb() computes > the hash of these concatenated areas and used it as DTB measurement. > - Remove useless default value 'n' for EFI_TCG2_PROTOCOL_MEASURE_DTB. > - I did not add EFI_TCG2_PROTOCOL_MEASURE_DTB dependencies on > !NET_RANDOM_ETHADDR neither on !CMD_KASLRSEED. If ethernet address > is random but always the same at each boot as saved in environment, > it's measure is meaningful. CMD_KASLRSEED effect in DT if already > addressed by efi_try_purge_kaslr_seed() prior measurement. That's correct, and since the TPM is guaranteed to have an RNG, we will always install the EFI_RNG protocol and get rid of kaslr-seed for the DT. > --- > cmd/bootefi.c | 8 +++++ > include/efi_loader.h | 2 ++ > include/efi_tcg2.h | 10 ++++++ > include/tpm-v2.h | 2 ++ > lib/efi_loader/Kconfig | 11 ++++++ > lib/efi_loader/efi_tcg2.c | 73 +++++++++++++++++++++++++++++++++++++++ > 6 files changed, 106 insertions(+) > > diff --git a/cmd/bootefi.c b/cmd/bootefi.c > index 2a7d42925d..6618335ddf 100644 > --- a/cmd/bootefi.c > +++ b/cmd/bootefi.c > @@ -332,6 +332,14 @@ efi_status_t efi_install_fdt(void *fdt) > > efi_try_purge_kaslr_seed(fdt); > > + if (CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL_MEASURE_DTB)) { > + ret = efi_tcg2_measure_dtb(fdt); > + if (ret == EFI_SECURITY_VIOLATION) { > + log_err("ERROR: failed to measure DTB\n"); > + return ret; > + } > + } > + > /* Install device tree as UEFI table */ > ret = efi_install_configuration_table(&efi_guid_fdt, fdt); > if (ret != EFI_SUCCESS) { > diff --git a/include/efi_loader.h b/include/efi_loader.h > index 4560b0d04c..4ecfdf919b 100644 > --- a/include/efi_loader.h > +++ b/include/efi_loader.h > @@ -531,6 +531,8 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void); > efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *handle); > /* Measure efi application exit */ > efi_status_t efi_tcg2_measure_efi_app_exit(void); > +/* Measure DTB */ > +efi_status_t efi_tcg2_measure_dtb(void *dtb); > /* Called by bootefi to initialize root node */ > efi_status_t efi_root_node_register(void); > /* Called by bootefi to initialize runtime */ > diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h > index 874306dc11..b1c3abd097 100644 > --- a/include/efi_tcg2.h > +++ b/include/efi_tcg2.h > @@ -233,6 +233,16 @@ struct efi_gpt_data { > gpt_entry partitions[]; > } __packed; > > +/** > + * struct tdUEFI_PLATFORM_FIRMWARE_BLOB2 > + * @blob_description_size: Byte size of @data > + * @data: Description data > + */ > +struct uefi_platform_firmware_blob2 { > + u8 blob_description_size; > + u8 data[]; > +} __packed; > + > struct efi_tcg2_protocol { > efi_status_t (EFIAPI * get_capability)(struct efi_tcg2_protocol *this, > struct efi_tcg2_boot_service_capability *capability); > diff --git a/include/tpm-v2.h b/include/tpm-v2.h > index 737e57551d..2df3dad553 100644 > --- a/include/tpm-v2.h > +++ b/include/tpm-v2.h > @@ -105,6 +105,8 @@ struct udevice; > "Exit Boot Services Returned with Failure" > #define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \ > "Exit Boot Services Returned with Success" > +#define EFI_DTB_EVENT_STRING \ > + "DTB DATA" > > /* TPMS_TAGGED_PROPERTY Structure */ > struct tpms_tagged_property { > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > index c56904afc2..c05a54df16 100644 > --- a/lib/efi_loader/Kconfig > +++ b/lib/efi_loader/Kconfig > @@ -346,6 +346,17 @@ config EFI_TCG2_PROTOCOL_EVENTLOG_SIZE > this is going to be allocated twice. One for the eventlog it self > and one for the configuration table that is required from the spec > > +config EFI_TCG2_PROTOCOL_MEASURE_DTB > + bool "Measure DTB with EFI_TCG2_PROTOCOL" > + depends on EFI_TCG2_PROTOCOL > + help > + When enabled, the DTB image passed to the booted EFI image is > + measured using the EFI TCG2 protocol. Do not enable this feature if > + the passed DTB contains data that change across platform reboots > + and cannot be used has a predictable measurement. Otherwise > + this feature allows better measurement of the system boot > + sequence. > + > config EFI_LOAD_FILE2_INITRD > bool "EFI_FILE_LOAD2_PROTOCOL for Linux initial ramdisk" > default y > diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c > index 918e9a2686..2dcc317157 100644 > --- a/lib/efi_loader/efi_tcg2.c > +++ b/lib/efi_loader/efi_tcg2.c > @@ -2175,6 +2175,79 @@ out1: > return ret; > } > > +/* Return the byte size of reserved map area in DTB or -1 upon error */ > +static ssize_t size_of_rsvmap(void *dtb) > +{ > + struct fdt_reserve_entry e; > + ssize_t size_max; > + ssize_t size; > + u8 *rsvmap_base; > + > + rsvmap_base = (u8 *)dtb + fdt_off_mem_rsvmap(dtb); > + size_max = fdt_totalsize(dtb) - fdt_off_mem_rsvmap(dtb); > + size = 0; > + > + do { > + memcpy(&e, rsvmap_base + size, sizeof(e)); > + size += sizeof(e); > + if (size > size_max) > + return -1; > + } while (e.size); > + > + return size; > +} > + > +/** > + * efi_tcg2_measure_dtb() - measure DTB passed to the OS > + * > + * @dtb: pointer to the device tree blob > + * > + * Return: status code > + */ > +efi_status_t efi_tcg2_measure_dtb(void *dtb) > +{ > + struct uefi_platform_firmware_blob2 *blob; > + struct fdt_header *header; > + sha256_context hash_ctx; > + struct udevice *dev; > + ssize_t rsvmap_size; > + efi_status_t ret; > + u32 event_size; > + > + if (!is_tcg2_protocol_installed()) > + return EFI_SUCCESS; > + > + ret = platform_get_tpm2_device(&dev); > + if (ret != EFI_SUCCESS) > + return EFI_SECURITY_VIOLATION; > + > + rsvmap_size = size_of_rsvmap(dtb); > + if (rsvmap_size < 0) > + return EFI_SECURITY_VIOLATION; Why is this a security violation? Maybe EFI_INVALID_PARAMETER? > + > + event_size = sizeof(*blob) + sizeof(EFI_DTB_EVENT_STRING) + SHA256_SUM_LEN; > + blob = calloc(1, event_size); > + if (!blob) > + return EFI_OUT_OF_RESOURCES; > + > + blob->blob_description_size = sizeof(EFI_DTB_EVENT_STRING); > + memcpy(blob->data, EFI_DTB_EVENT_STRING, blob->blob_description_size); > + > + /* Measure populated areas of the DTB */ > + header = dtb; > + sha256_starts(&hash_ctx); > + sha256_update(&hash_ctx, (u8 *)header, sizeof(struct fdt_header)); > + sha256_update(&hash_ctx, (u8 *)dtb + fdt_off_dt_struct(dtb), fdt_size_dt_strings(dtb)); > + sha256_update(&hash_ctx, (u8 *)dtb + fdt_off_dt_strings(dtb), fdt_size_dt_struct(dtb)); > + sha256_update(&hash_ctx, (u8 *)dtb + fdt_off_mem_rsvmap(dtb), rsvmap_size); > + sha256_finish(&hash_ctx, blob->data + blob->blob_description_size); > + > + ret = tcg2_measure_event(dev, 0, EV_POST_CODE, event_size, (u8 *)blob); > + > + free(blob); > + return ret; > +} > + > /** > * efi_tcg2_measure_efi_app_invocation() - measure efi app invocation > * > -- > 2.25.1 > With the return code changed Tested-by: Ilias Apalodimas Reviewed-by: Ilias Apalodimas