From patchwork Fri Aug 13 07:12:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 496550 Delivered-To: patch@linaro.org Received: by 2002:a02:cf8a:0:0:0:0:0 with SMTP id w10csp273760jar; Fri, 13 Aug 2021 00:12:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxSI12s0BK+8zm1MFZc8cPT481uBLeCOLu/IpYC7O5V4Sj1TBNYq3g3GL7cCIKXCxW3Pg10 X-Received: by 2002:a05:6402:440e:: with SMTP id y14mr1347864eda.238.1628838775978; Fri, 13 Aug 2021 00:12:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628838775; cv=none; d=google.com; s=arc-20160816; b=S4u0uREB7CHGYyvSIn9vabzsDeMxPOaaz52QWwnbKsrDFikh7XneT0X5BgjHe+oHmk e0GVOVwvJiPEdtrC7gSVYgsWOlMQs9J8LCIILbzoPnq0lbGegkowW/z5jvNh4BCrsdEW rwmqJifX83l4dJIFC8U9BCq15TWR1/mzWZyYf0fzykQf4NVM7gDgKG6TnDRsuFjJd+3A Pa22IYXby0Cx8ihFfhAStNd30gwW4Mwda2+xqlfiWZXgsjwO8yOqrjEMMR569U/4BrBA 0yKOO5ZOACSP9a5Z0ZFs5oM17yapq3wd3AJzRtLEft/Wsn4t7W0VYSxp8Wz/KfcC37ZQ CcMQ== 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:references:in-reply-to :message-id:date:subject:to:from:dkim-signature; bh=HxVy8JBaVCnsb6ozYjiq5FldXudeiYMpi/b6S06NAxw=; b=IQvA/Z+Y5GQcpjrUTjWLtzQW85eVfj7XIEM7FSOe0jnDJWl5mfkshyv/dumkI9O+qe R9iDA17j7Rhc5WTzKk5vMaJ/QHNozIgDfFx0IpeLI1v0gLNDYvXbckYSWOSVfkNs6P13 d/K8DdLmBwMiLAINkx0jXl1K4wTRorzW+N3u4MspyK+WXkblLMxdCAecsBSVzyPC7ymz ApIx+XtLOyHEObiGsCOwevj/NBxcBeRr9a3EDRWhVC5g/Hs/r7eRgGe0/dnHEvGO5wcA pcpozqFmsIMc4yJr4FBWN8AS3lz4kuMYYZhOVND7dZiWBJp3YvJ2zVemfJ9DT3VDqxMp LvzA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=PHj3UXqw; 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 j17si717175ejm.446.2021.08.13.00.12.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Aug 2021 00:12:55 -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=PHj3UXqw; 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 7F47882DE8; Fri, 13 Aug 2021 09:12:44 +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="PHj3UXqw"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6B5E182DD9; Fri, 13 Aug 2021 09:12:34 +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.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) (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 165EB8296F for ; Fri, 13 Aug 2021 09:12:26 +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=masahisa.kojima@linaro.org Received: by mail-pl1-x62c.google.com with SMTP id e15so10685240plh.8 for ; Fri, 13 Aug 2021 00:12:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=HxVy8JBaVCnsb6ozYjiq5FldXudeiYMpi/b6S06NAxw=; b=PHj3UXqwgtdrJ/onvs6V9G11GqoswNmOF9EGQlWLyv64Vw96B4WgR/pof+S9xVxmjh w/HoyfQbmfrx1ocNu60PmpZAW43i8puOliOODk+oYpHeV5WbpUtVe4A5cnrn4YPYcep5 L3iQIUVniVIlTOHElKBUyIOh/RUjEl6eU5VELgDp7+cQAQkhtpSaPxw/br7xlUUnWDxf s2bpHP7hThzh5tU4TllY4pNFMnhO5ACGzZbpMDJBPTcP/Q+643BJUV56cQuwmwJu8dVW 0/drRsMXauUF86Xri+1mdJJ8+EMtQoG/896k3LfhgZMYj12Jyv3lrqTDry/hM+kjzC3V NhKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=HxVy8JBaVCnsb6ozYjiq5FldXudeiYMpi/b6S06NAxw=; b=Y/e1xn+O0cShzlaD6RWDcgdhoW33kK4O3FmJp7y8nLcvhY5SEwFxvFbX0u+nr/cRLh sdNSL+CCPDbLBuvhW1TXisAzD3yqCPimf3Jy8UN1CkJn1RILbEvxxyrAl+dHC5MdIWUu tev0+a3xMt/ZvrrRVh2NPoXfO06ppN6v9Jfrsb9N+CDrTZrng3UxmXBC0Ix5eQrjFRTc eMQByaNeKbMMhTNbIG90IM7tE99XsDiiiMrEOkSa951uFy21hHi96HFJ27oOuFhAUJS1 oLZv1ACmWkF4Mv2L4SwdJ1pzIb0NHD9j3yUtA/L4PJ8tBd8kFzxCvUmNvY+Ob2vALlFd F/qQ== X-Gm-Message-State: AOAM531oZZYvktIOMKjYTctAlEsuaV7HtXEw+/HQEJ4pfDCC2rqTffC0 l09IfpqTPjJWvknaXhMA7DJ2fA== X-Received: by 2002:a17:903:2292:b0:12d:91c3:bd95 with SMTP id b18-20020a170903229200b0012d91c3bd95mr1032137plh.23.1628838744063; Fri, 13 Aug 2021 00:12:24 -0700 (PDT) Received: from localhost.localdomain ([2400:2411:502:a100:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id u21sm987078pfh.163.2021.08.13.00.12.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Aug 2021 00:12:23 -0700 (PDT) From: Masahisa Kojima To: Heinrich Schuchardt , Alexander Graf , Ilias Apalodimas , Simon Glass , Masahisa Kojima , Dhananjay Phadke , AKASHI Takahiro , u-boot@lists.denx.de Subject: [PATCH v4 2/5] efi_loader: add boot variable measurement Date: Fri, 13 Aug 2021 16:12:40 +0900 Message-Id: <20210813071243.18885-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210813071243.18885-1-masahisa.kojima@linaro.org> References: <20210813071243.18885-1-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.2 at phobos.denx.de X-Virus-Status: Clean TCG PC Client PFP spec requires to measure "Boot####" and "BootOrder" variables, EV_SEPARATOR event prior to the Ready to Boot invocation. Since u-boot does not implement Ready to Boot event, these measurements are performed when efi_start_image() is called. TCG spec also requires to measure "Calling EFI Application from Boot Option" for each boot attempt, and "Returning from EFI Application from Boot Option" if a boot device returns control back to the Boot Manager. Signed-off-by: Masahisa Kojima --- Changes in v4: - remove unnecessary EFIAPI specifier Changes in v3: - modify log output Changes in v2: - use efi_create_indexed_name() for "Boot####" variable include/efi_loader.h | 4 ++ include/tpm-v2.h | 18 ++++- lib/efi_loader/efi_boottime.c | 20 ++++++ lib/efi_loader/efi_tcg2.c | 121 ++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 1 deletion(-) -- 2.17.1 diff --git a/include/efi_loader.h b/include/efi_loader.h index a120d94431..6f61e9faac 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -499,6 +499,10 @@ efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size); efi_status_t efi_init_variables(void); /* Notify ExitBootServices() is called */ void efi_variables_boot_exit_notify(void); +/* Measure efi application invocation */ +efi_status_t efi_tcg2_measure_efi_app_invocation(void); +/* Measure efi application exit */ +efi_status_t efi_tcg2_measure_efi_app_exit(void); /* 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/tpm-v2.h b/include/tpm-v2.h index 247b386967..325c73006e 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -73,7 +73,7 @@ struct udevice; /* * event types, cf. * "TCG PC Client Platform Firmware Profile Specification", Family "2.0" - * rev 1.04, June 3, 2019 + * Level 00 Version 1.05 Revision 23, May 7, 2021 */ #define EV_EFI_EVENT_BASE ((u32)0x80000000) #define EV_EFI_VARIABLE_DRIVER_CONFIG ((u32)0x80000001) @@ -85,8 +85,24 @@ struct udevice; #define EV_EFI_ACTION ((u32)0x80000007) #define EV_EFI_PLATFORM_FIRMWARE_BLOB ((u32)0x80000008) #define EV_EFI_HANDOFF_TABLES ((u32)0x80000009) +#define EV_EFI_PLATFORM_FIRMWARE_BLOB2 ((u32)0x8000000A) +#define EV_EFI_HANDOFF_TABLES2 ((u32)0x8000000B) +#define EV_EFI_VARIABLE_BOOT2 ((u32)0x8000000C) #define EV_EFI_HCRTM_EVENT ((u32)0x80000010) #define EV_EFI_VARIABLE_AUTHORITY ((u32)0x800000E0) +#define EV_EFI_SPDM_FIRMWARE_BLOB ((u32)0x800000E1) +#define EV_EFI_SPDM_FIRMWARE_CONFIG ((u32)0x800000E2) + +#define EFI_CALLING_EFI_APPLICATION \ + "Calling EFI Application from Boot Option" +#define EFI_RETURNING_FROM_EFI_APPLICATION \ + "Returning from EFI Application from Boot Option" +#define EFI_EXIT_BOOT_SERVICES_INVOCATION \ + "Exit Boot Services Invocation" +#define EFI_EXIT_BOOT_SERVICES_FAILED \ + "Exit Boot Services Returned with Failure" +#define EFI_EXIT_BOOT_SERVICES_SUCCEEDED \ + "Exit Boot Services Returned with Success" /* TPMS_TAGGED_PROPERTY Structure */ struct tpms_tagged_property { diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 0b98e91813..13ab139222 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2994,6 +2994,16 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, image_obj->exit_status = &exit_status; image_obj->exit_jmp = &exit_jmp; + if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { + if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) { + ret = efi_tcg2_measure_efi_app_invocation(); + if (ret != EFI_SUCCESS) { + log_warning("tcg2 measurement fails(0x%lx)\n", + ret); + } + } + } + /* call the image! */ if (setjmp(&exit_jmp)) { /* @@ -3252,6 +3262,16 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, exit_status != EFI_SUCCESS) efi_delete_image(image_obj, loaded_image_protocol); + if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { + if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) { + ret = efi_tcg2_measure_efi_app_exit(); + if (ret != EFI_SUCCESS) { + log_warning("tcg2 measurement fails(0x%lx)\n", + ret); + } + } + } + /* Make sure entry/exit counts for EFI world cross-overs match */ EFI_EXIT(exit_status); diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index db3d6d7586..ed71337780 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -35,6 +35,7 @@ struct event_log_buffer { }; static struct event_log_buffer event_log; +static bool tcg2_efi_app_invoked; /* * When requesting TPM2_CAP_TPM_PROPERTIES the value is on a standard offset. * Since the current tpm2_get_capability() response buffers starts at @@ -1385,6 +1386,126 @@ static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index, return ret; } +/** + * tcg2_measure_boot_variable() - measure boot variables + * + * @dev: TPM device + * + * Return: status code + */ +static efi_status_t tcg2_measure_boot_variable(struct udevice *dev) +{ + u16 *boot_order; + u16 *boot_index; + u16 var_name[] = L"BootOrder"; + u16 boot_name[] = L"Boot####"; + u8 *bootvar; + efi_uintn_t var_data_size; + u32 count, i; + efi_status_t ret; + + boot_order = efi_get_var(var_name, &efi_global_variable_guid, + &var_data_size); + if (!boot_order) { + ret = EFI_NOT_FOUND; + goto error; + } + + ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, var_name, + &efi_global_variable_guid, var_data_size, + (u8 *)boot_order); + if (ret != EFI_SUCCESS) + goto error; + + count = var_data_size / sizeof(*boot_order); + boot_index = boot_order; + for (i = 0; i < count; i++) { + efi_create_indexed_name(boot_name, sizeof(boot_name), + "Boot", *boot_index++); + + bootvar = efi_get_var(boot_name, &efi_global_variable_guid, + &var_data_size); + + if (!bootvar) { + log_info("%ls not found\n", boot_name); + continue; + } + + ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, + boot_name, + &efi_global_variable_guid, + var_data_size, bootvar); + free(bootvar); + if (ret != EFI_SUCCESS) + goto error; + } + +error: + free(boot_order); + return ret; +} + +/** + * efi_tcg2_measure_efi_app_invocation() - measure efi app invocation + * + * Return: status code + */ +efi_status_t efi_tcg2_measure_efi_app_invocation(void) +{ + efi_status_t ret; + u32 pcr_index; + struct udevice *dev; + u32 event = 0; + + if (tcg2_efi_app_invoked) + return EFI_SUCCESS; + + ret = platform_get_tpm2_device(&dev); + if (ret != EFI_SUCCESS) + return ret; + + ret = tcg2_measure_boot_variable(dev); + if (ret != EFI_SUCCESS) + goto out; + + ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION, + strlen(EFI_CALLING_EFI_APPLICATION), + (u8 *)EFI_CALLING_EFI_APPLICATION); + if (ret != EFI_SUCCESS) + goto out; + + for (pcr_index = 0; pcr_index <= 7; pcr_index++) { + ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR, + sizeof(event), (u8 *)&event); + if (ret != EFI_SUCCESS) + goto out; + } + + tcg2_efi_app_invoked = true; +out: + return ret; +} + +/** + * efi_tcg2_measure_efi_app_exit() - measure efi app exit + * + * Return: status code + */ +efi_status_t efi_tcg2_measure_efi_app_exit(void) +{ + efi_status_t ret; + struct udevice *dev; + + ret = platform_get_tpm2_device(&dev); + if (ret != EFI_SUCCESS) + return ret; + + ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION, + strlen(EFI_RETURNING_FROM_EFI_APPLICATION), + (u8 *)EFI_RETURNING_FROM_EFI_APPLICATION); + return ret; +} + /** * tcg2_measure_secure_boot_variable() - measure secure boot variables *