From patchwork Fri Aug 6 07:02:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 492806 Delivered-To: patch@linaro.org Received: by 2002:a05:6638:396:0:0:0:0 with SMTP id y22csp45144jap; Fri, 6 Aug 2021 00:03:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyeBWDuuYMm8Yyb5dD5Xqn44YniCXXommMSS/tdFmbw0UwgMMr1sBfE2PgI2ysxjwHKeFMY X-Received: by 2002:a05:6402:3481:: with SMTP id v1mr10804201edc.60.1628233396680; Fri, 06 Aug 2021 00:03:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1628233396; cv=none; d=google.com; s=arc-20160816; b=VlNY7apVnsgT8dv9bww5uFwhmyPcCpN2UstJF3GTd19ISZ0tyIMW1OiGbhnSLcw/tq MdOTNErqRztY7O2vZjVwUO5XlJ9xtCdhSS94mPA7hUPnVT1VVhH6D+5/e41KImzNOgh4 dqT56CGcbOGhNWvNq7zMmW5sJM6W1aRybdpUaAGsKfgrsr0w7NmP5dd6R1UGEaO6Gtpt adiBXUuu59U+us7/WzlmLZm1BGV6YUktlj9PNTpTVexVCxjFaO628yRJSAWk3cQ0U2GW yIG3Sd0Dr8dna+RsyicT3WfJt0G2kD3zcZ1l6L96rANA7+za9IgDUj8lCaQaqNATBIFa T4ug== 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=l7uLbbzmQcCQQtrwe9xF/acuDiHco9zb2Hjf2C+tE48=; b=y5bCO2hl8VopZr+Q/NBd94SDwR1jCdlGPH7o0kOOXI8+yqqRII15TwDwVfWlCFN8xE 12JhKn5mSqEY7ntGtMDK0H4TF3A6QNpZ/O07bgKkrtJqjwquZ0q/Y8gWNcrrgG5eThR0 u6bAjxKRuCA8NEzCDX7WpJ1aZFYvfQFxwtpwnp55I1z2p1Q12b0pgYLgcReIrdkKbKQb HQAUFJqGMXAQ/6E4BrMZQyqN1VzBOqz77OW0rVaSkWgy5z+yxxT0tuTrDEro4akcq9Fh jvjspalt0mouppPkPKnEUxtLBvNDMLdny6gWS3lg0R3ta/n3997UiWo1QG6TV6L26Xwt t0oA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GoYjrHsi; 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 u1si6270090edo.320.2021.08.06.00.03.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Aug 2021 00:03:16 -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=GoYjrHsi; 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 975CB82E83; Fri, 6 Aug 2021 09:03:06 +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="GoYjrHsi"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0611582E7D; Fri, 6 Aug 2021 09:03:04 +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-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) (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 AC36B82E23 for ; Fri, 6 Aug 2021 09:02:56 +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-x1034.google.com with SMTP id o44-20020a17090a0a2fb0290176ca3e5a2fso15946360pjo.1 for ; Fri, 06 Aug 2021 00:02:56 -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=l7uLbbzmQcCQQtrwe9xF/acuDiHco9zb2Hjf2C+tE48=; b=GoYjrHsiWm8jkBGurqrOxIKKqc/FvJTy+vZzwbReuTP1mw54Jw6v7N27O+dCcnZ16V kxxMWMfMRL5kjVQnMt6fhH4DDj3HmeKkJlI1BitNPVkPj7KowOTP+G2IDitXx81FGuVo 1X/of3v2kHyZNjuhrZbD2EQ3Ycmfxla1kd6Gy4sV2h3y0wRJnlJe0bp24JlL3bqY4dA8 qM9qXuB8HNMsTgyp2gWAbmwwQiDpK4dK3myzDw9Q/fg5gevaeJV8STm5E9uuk9POLI1P FCe1j9YfubHarAQBe+C35QTBewEpqCrD0jFXqrRR1jBMR+fepYWdE+MtJpjlWm2VlvFA Tjzg== 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=l7uLbbzmQcCQQtrwe9xF/acuDiHco9zb2Hjf2C+tE48=; b=Jjy+yCcxOx7TzjNmObbCuXN8NEBndD1yZCyWwHfGTWyWSkRXTf7wzS8FtWELoeM7rh WGVLJJiHRObD/c+DSRUkUEdlV2jngiElmn1FUd9+wH5wSTJnMvxmQiN1NJFKPCYs3qT7 9nRy+wyteGy1wHW8PgkZBQ55mWicoAY2O6r9ASsGJEXReRvszvHWfKlM1MZLpYQpOOCw yEGIpCiMZ8Q204RftE1bN/pDFsO0solSIhHrKY45YuVEKr/63DiFqXFC3MX3Z3lqbien 26oVWE8ovdwt54pIZe2qRndk1GsVw2cUEgRPEab/SbqlQXDcZClqPmh2lWwYi8tYOZiw RKrg== X-Gm-Message-State: AOAM532wtxj/5xzTVHiy4mn4DVAcbxakRh73+u9F4WHZuWPjKycowu02 avyNHxTFY0S8bD9vuRfbhZgHnQ== X-Received: by 2002:a17:902:e890:b029:12c:d32a:9fe8 with SMTP id w16-20020a170902e890b029012cd32a9fe8mr7270950plg.70.1628233375095; Fri, 06 Aug 2021 00:02:55 -0700 (PDT) Received: from localhost.localdomain ([2400:2411:502:a100:82fa:5bff:fe4b:26b1]) by smtp.gmail.com with ESMTPSA id u24sm5145304pfm.27.2021.08.06.00.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Aug 2021 00:02:54 -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 v3 1/5] efi_loader: add secure boot variable measurement Date: Fri, 6 Aug 2021 16:02:11 +0900 Message-Id: <20210806070215.19887-2-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210806070215.19887-1-masahisa.kojima@linaro.org> References: <20210806070215.19887-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 the secure boot policy before validating the UEFI image. This commit adds the secure boot variable measurement of "SecureBoot", "PK", "KEK", "db", "dbx", "dbt", and "dbr". Note that this implementation assumes that secure boot variables are pre-configured and not be set/updated in runtime. Signed-off-by: Masahisa Kojima --- Changes in v3: - add "dbt" and "dbr" measurement - accept empty variable measurement for "SecureBoot", "PK", "KEK", "db" and "dbx" as TCG2 spec requires - fix comment format Changes in v2: - missing null check for getting variable data - some minor fix for readability include/efi_tcg2.h | 20 +++++ lib/efi_loader/efi_tcg2.c | 165 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) -- 2.17.1 diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h index bcfb98168a..497ba3ce94 100644 --- a/include/efi_tcg2.h +++ b/include/efi_tcg2.h @@ -142,6 +142,26 @@ struct efi_tcg2_final_events_table { struct tcg_pcr_event2 event[]; }; +/** + * struct tdUEFI_VARIABLE_DATA - event log structure of UEFI variable + * @variable_name: The vendorGUID parameter in the + * GetVariable() API. + * @unicode_name_length: The length in CHAR16 of the Unicode name of + * the variable. + * @variable_data_length: The size of the variable data. + * @unicode_name: The CHAR16 unicode name of the variable + * without NULL-terminator. + * @variable_data: The data parameter of the efi variable + * in the GetVariable() API. + */ +struct efi_tcg2_uefi_variable_data { + efi_guid_t variable_name; + u64 unicode_name_length; + u64 variable_data_length; + u16 unicode_name[1]; + u8 variable_data[1]; +}; + 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/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 1319a8b378..a2e9587cd0 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -78,6 +78,19 @@ static const struct digest_info hash_algo_list[] = { }, }; +struct variable_info { + u16 *name; + const efi_guid_t *guid; +}; + +static struct variable_info secure_variables[] = { + {L"SecureBoot", &efi_global_variable_guid}, + {L"PK", &efi_global_variable_guid}, + {L"KEK", &efi_global_variable_guid}, + {L"db", &efi_guid_image_security_database}, + {L"dbx", &efi_guid_image_security_database}, +}; + #define MAX_HASH_COUNT ARRAY_SIZE(hash_algo_list) /** @@ -1264,6 +1277,39 @@ free_pool: return ret; } +/** + * tcg2_measure_event() - common function to add event log and extend PCR + * + * @dev: TPM device + * @pcr_index: PCR index + * @event_type: type of event added + * @size: event size + * @event: event data + * + * Return: status code + */ +static efi_status_t EFIAPI +tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type, + u32 size, u8 event[]) +{ + struct tpml_digest_values digest_list; + efi_status_t ret; + + ret = tcg2_create_digest(event, size, &digest_list); + if (ret != EFI_SUCCESS) + goto out; + + ret = tcg2_pcr_extend(dev, pcr_index, &digest_list); + if (ret != EFI_SUCCESS) + goto out; + + ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list, + size, event); + +out: + return ret; +} + /** * efi_append_scrtm_version - Append an S-CRTM EV_S_CRTM_VERSION event on the * eventlog and extend the PCRs @@ -1294,6 +1340,118 @@ out: return ret; } +/** + * tcg2_measure_variable() - add variable event log and extend PCR + * + * @dev: TPM device + * @pcr_index: PCR index + * @event_type: type of event added + * @var_name: variable name + * @guid: guid + * @data_size: variable data size + * @data: variable data + * + * Return: status code + */ +static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index, + u32 event_type, u16 *var_name, + const efi_guid_t *guid, + efi_uintn_t data_size, u8 *data) +{ + u32 event_size; + efi_status_t ret; + struct efi_tcg2_uefi_variable_data *event; + + event_size = sizeof(event->variable_name) + + sizeof(event->unicode_name_length) + + sizeof(event->variable_data_length) + + (u16_strlen(var_name) * sizeof(u16)) + data_size; + event = malloc(event_size); + if (!event) + return EFI_OUT_OF_RESOURCES; + + guidcpy(&event->variable_name, guid); + event->unicode_name_length = u16_strlen(var_name); + event->variable_data_length = data_size; + memcpy(event->unicode_name, var_name, + (event->unicode_name_length * sizeof(u16))); + if (data) { + memcpy((u16 *)event->unicode_name + event->unicode_name_length, + data, data_size); + } + ret = tcg2_measure_event(dev, pcr_index, event_type, event_size, + (u8 *)event); + free(event); + return ret; +} + +/** + * tcg2_measure_secure_boot_variable() - measure secure boot variables + * + * @dev: TPM device + * + * Return: status code + */ +static efi_status_t tcg2_measure_secure_boot_variable(struct udevice *dev) +{ + u8 *data; + efi_uintn_t data_size; + u32 count, i; + efi_status_t ret; + + count = ARRAY_SIZE(secure_variables); + for (i = 0; i < count; i++) { + /* + * According to the TCG2 PC Client PFP spec, "SecureBoot", + * "PK", "KEK", "db" and "dbx" variables must be measured + * even if they are empty. + */ + data = efi_get_var(secure_variables[i].name, + secure_variables[i].guid, + &data_size); + + ret = tcg2_measure_variable(dev, 7, + EV_EFI_VARIABLE_DRIVER_CONFIG, + secure_variables[i].name, + secure_variables[i].guid, + data_size, data); + free(data); + if (ret != EFI_SUCCESS) + goto error; + } + + /* + * TCG2 PC Client PFP spec says "dbt" and "dbr" are + * measured if present and not empty. + */ + data = efi_get_var(L"dbt", + &efi_global_variable_guid, + &data_size); + if (data) { + ret = tcg2_measure_variable(dev, 7, + EV_EFI_VARIABLE_DRIVER_CONFIG, + L"dbt", + &efi_global_variable_guid, + data_size, data); + free(data); + } + + data = efi_get_var(L"dbr", + &efi_global_variable_guid, + &data_size); + if (data) { + ret = tcg2_measure_variable(dev, 7, + EV_EFI_VARIABLE_DRIVER_CONFIG, + L"dbr", + &efi_global_variable_guid, + data_size, data); + free(data); + } + +error: + return ret; +} + /** * efi_tcg2_register() - register EFI_TCG2_PROTOCOL * @@ -1328,6 +1486,13 @@ efi_status_t efi_tcg2_register(void) tcg2_uninit(); goto fail; } + + ret = tcg2_measure_secure_boot_variable(dev); + if (ret != EFI_SUCCESS) { + tcg2_uninit(); + goto fail; + } + return ret; fail: