From patchwork Wed Jul 14 13:00:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 476742 Delivered-To: patch@linaro.org Received: by 2002:a02:c94a:0:0:0:0:0 with SMTP id u10csp545185jao; Wed, 14 Jul 2021 06:00:01 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyhd1nWfbIH2qWlwcCOGbqM0zLC6p8A7xoG7JJlwSTTzMMM8BgjR49coyrrlHeaADiZJIoL X-Received: by 2002:aa7:cb19:: with SMTP id s25mr13744006edt.194.1626267601540; Wed, 14 Jul 2021 06:00:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626267601; cv=none; d=google.com; s=arc-20160816; b=EXdtk8iCQ3qgpSJCromy7CEr9l7eCR19WT8OFhhCh4R55JVkm+VDK1aA7OTaUqqtCC 35WWXcbBDWn46ieLgWw4fINHeOb68RQqnhu2H1T4bqJhiX8X/q9gbfkvmvXP+eCqGSUZ hZfZq6cOJ/XkjVS/O9KpCIMvXoBA3iJZr3g6vRRKyUpnbTvSBdNWnNYD93Pk8p+aQ3DE 7nqDCEr3nzDGlmAqfJeI6CniAI5fJEg3cvM7gGGXGRXxlWL+U+w3AZZ0cFqncJVw2INF Rmf4fj9/fo7KXNujMD4yppJTCnJ3xzhyKfSRYKpeZcCH1mGlnBmNPBDm32wyby/0l2sK tHEg== 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=9vb0IigBLO56hsEskR74tTxD6tfP8jNyWZE9oPxUhnM=; b=B3nGMMfRk0mOFcyjKr49iKhHvjj6lSyLmxE3jTYBS7L0j+4ebb1rRLquFs9A7oLmOn twy0r/f/tgsfbzX4QbNThnMd1sM+MlFbgCTRA0IMhRYCMJGmKL3ZmlIo3QvQby/v4dUt GD48RSOC4g7SL5rCeuNZa0n4iQ1+3gpkOjddPZIyOgd55ZEGzuTciTLQCkIRe2xdbxBb EDp/6PnM+pUqH72j1pT7bJDShOZVVGdftPuZh5R7K7Ho8NDzyapjLWd7g9k7wBpX1vF4 lZofNH5Tl/kRT/LFPQGSAxWWA5ZEz894nzqqoRC5PVRvJHtrQF2tte5R3hK7o3oofjb5 2I+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="uu/PDoGM"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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. [85.214.62.61]) by mx.google.com with ESMTPS id l7si3080243edk.216.2021.07.14.06.00.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Jul 2021 06:00:01 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="uu/PDoGM"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 6F59782005; Wed, 14 Jul 2021 14:59:42 +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="uu/PDoGM"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 60C418201E; Wed, 14 Jul 2021 14:59:35 +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-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) (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 03CF4812A6 for ; Wed, 14 Jul 2021 14:59:30 +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-pj1-x1030.google.com with SMTP id jx7-20020a17090b46c7b02901757deaf2c8so1384894pjb.0 for ; Wed, 14 Jul 2021 05:59:29 -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=9vb0IigBLO56hsEskR74tTxD6tfP8jNyWZE9oPxUhnM=; b=uu/PDoGM+0EtlEbw375xesMJx6dS+vYWRvAhA8vls1dHMinagwF520rbq1vw3Irliy fi83XIyon1+gKYiaJdVODvjwtQlbNHuxZeTq7gW4TqHeWFHJyxp7yuWH8zF0qLUlNYzP DUXunYiLHQYqJpQR6nsPE7u4AjowRVzwS9QE5s8/vO5BVSa2bwOBOgyNpduuq2lCGoKx gwdJvhdLGnTwJBfkz5HS9eKj9N4dQOqEUUGgrE+KtlE8A6kGAiM7CneoJ1PYRLRuGtYM /wYzU2Stxuv0zkNkfAWZfQDbdiLPWy/qLwnSt0E9cAVpdTGVe1ocRvHWC2lpUaN5wj2W 77VQ== 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=9vb0IigBLO56hsEskR74tTxD6tfP8jNyWZE9oPxUhnM=; b=A7c2J3A5IBvGWbFl3kltX9qU8xb2cErouaprYuX4+5oWPrf/M3Ibo42T+cwCGggiV0 xLZanFdj/CAuCq42BHEmCkJJmm92t4wzJBzAIQHd+QkUDyFQQkqYW7tRBFxjvWb85yHY jaEDjxmpT9trxocedxlOA86DEHs8kmttKAz2heCgviCUl9cWN14t47kyvQV0n4EFSOCV hg1RwT7HfTwOE1jISj3i5qP+JosFQd/51nZs8KQXeN/lpIohhK38IgOKoUzmS05+MR4z xssNeqE+hBUMT/fWSFY4ReCI48Kp0Swmw3vw9woNVpenB3FzYxyfPLX97oIbEXWkEys2 zl9Q== X-Gm-Message-State: AOAM532K0Z16z+mSBjjchUexYTzkgGqujewQC02YqgFaBTdb0uF+KS1n Kfjos0+2U++JH+XXyFT5WHiowQ== X-Received: by 2002:a17:90a:4988:: with SMTP id d8mr9598860pjh.85.1626267568376; Wed, 14 Jul 2021 05:59:28 -0700 (PDT) Received: from localhost.localdomain ([2400:2411:502:a100:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id m21sm2787509pfo.159.2021.07.14.05.59.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Jul 2021 05:59:27 -0700 (PDT) From: Masahisa Kojima To: Heinrich Schuchardt , Alexander Graf , Ilias Apalodimas , Simon Glass , Masahisa Kojima , Dhananjay Phadke , u-boot@lists.denx.de Subject: [PATCH v2 3/6] efi_loader: add boot variable measurement Date: Wed, 14 Jul 2021 22:00:03 +0900 Message-Id: <20210714130006.17837-4-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210714130006.17837-1-masahisa.kojima@linaro.org> References: <20210714130006.17837-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 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 b81180cfda..703b675950 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -407,6 +407,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 EFIAPI efi_tcg2_measure_efi_app_invocation(void); +/* Measure efi application exit */ +efi_status_t EFIAPI 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 f6d5ba05e3..2914800c56 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2993,6 +2993,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) { + EFI_PRINT("tcg2 measurement fails(0x%lx)\n", + ret); + } + } + } + /* call the image! */ if (setjmp(&exit_jmp)) { /* @@ -3251,6 +3261,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) { + EFI_PRINT("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 12db6f6b7c..d59fc5a890 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 @@ -1383,6 +1384,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) { + log_info("BootOrder not defined\n"); + 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 EFIAPI 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 EFIAPI 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 *