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 X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 949E7C4338F for ; Tue, 10 Aug 2021 01:44:37 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id A150360F6F for ; Tue, 10 Aug 2021 01:44:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A150360F6F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 212E5817D3; Tue, 10 Aug 2021 03:44:34 +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="ZBpaazFe"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3C42281E47; Tue, 10 Aug 2021 03:44:32 +0200 (CEST) Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) (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 B699380FB4 for ; Tue, 10 Aug 2021 03: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=takahiro.akashi@linaro.org Received: by mail-pj1-x1029.google.com with SMTP id w13-20020a17090aea0db029017897a5f7bcso2908846pjy.5 for ; Mon, 09 Aug 2021 18:44:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:mail-followup-to:references :mime-version:content-disposition:in-reply-to; bh=MFe6wo5zM/N14qIicL+CuS/cxmRz+K33AZPss+DWX/c=; b=ZBpaazFeFu1eUMHnyxozGf1B92A1x+LpcCV/bP3LU3bGdzhOEPcpZzOJEP6q9arogp jTHlFyQIjThkx7RkrykgQ+Mj5umIteGoM4SvFOoidQSbk6lO8Rfa99+e272Ws1bpHAfq N5v0Vu7GX3VGNus0f5zPND12yaiV703rjmT7AFv/nb1X4q7VZmCCOm1GH8+kPR3CQCqE YgLBZkn4+qG0Snya8UcEdA1QFKOE3QpdNtOIos3nneptgh6bkSi2LUA9U3lunRoZ6dev npdPAB1M0I5Atn273ianJIK5ivGyJbmL7xKdEDampXgqDUxJdVQqMQatDeLjj+T/iQws 8aMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id :mail-followup-to:references:mime-version:content-disposition :in-reply-to; bh=MFe6wo5zM/N14qIicL+CuS/cxmRz+K33AZPss+DWX/c=; b=QkSjkhNlKR/Jc3Mp247qZupLci0BuvIvRYZC7rQyUW2nqkznLbM66HLTTqY4wtVSrY g7m9APJy0kNiBlqoNYVKUFA3tTl3svoK2bdZNb3Mp+OPNOYjcjhv8x/MQyHv9dCuPqJu h76ENF+f7rRfcXhjG5trrOa7a+yS1hn6qwat2PXdubdG9EWNbeZrCqpsTb6VP8AZs9Wf 5/0HF9C97pg5KCgTfKTnVufHbmhw56vqUGS/s+K2kHScu4RToNnEa9QEx2Ij6CgSq1Sx GsDNUiI/HLgQFXDfDw7aVE/wN/+GjonYi7USxGcxfgSxq3zUgc7+C6EgT2FkqUxENULZ 3qVw== X-Gm-Message-State: AOAM5336bmyHdTgDCvdT+ezMxYix5A5zwDk3sJuM/lojG7mgp55fdPJg eiV5DmtN+HYtRaHIgIjO85z3Yg== X-Google-Smtp-Source: ABdhPJwpq8nFbHNJOfGSAjpUJIsjk8HN2iSqASI33vQ/olqhUrIje1qYAIOptcn993iHBfm42Bo7ow== X-Received: by 2002:a17:90a:d991:: with SMTP id d17mr254573pjv.54.1628559865721; Mon, 09 Aug 2021 18:44:25 -0700 (PDT) Received: from laputa (pdb6272e8.tkyea130.ap.so-net.ne.jp. [219.98.114.232]) by smtp.gmail.com with ESMTPSA id k25sm21105468pfa.213.2021.08.09.18.44.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Aug 2021 18:44:24 -0700 (PDT) Date: Tue, 10 Aug 2021 10:44:20 +0900 From: AKASHI Takahiro To: Masahisa Kojima Cc: Heinrich Schuchardt , Alexander Graf , Ilias Apalodimas , Simon Glass , Dhananjay Phadke , u-boot@lists.denx.de Subject: Re: [PATCH v3 1/5] efi_loader: add secure boot variable measurement Message-ID: <20210810014420.GA11600@laputa> Mail-Followup-To: AKASHI Takahiro , Masahisa Kojima , Heinrich Schuchardt , Alexander Graf , Ilias Apalodimas , Simon Glass , Dhananjay Phadke , u-boot@lists.denx.de References: <20210806070215.19887-1-masahisa.kojima@linaro.org> <20210806070215.19887-2-masahisa.kojima@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210806070215.19887-2-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 Kojima-san, On Fri, Aug 06, 2021 at 04:02:11PM +0900, Masahisa Kojima wrote: > 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(+) > > 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. > + */ The current implementation of secure boot doesn't support neither dbt or dbr. Do we have to measure them now? I think that EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION bit in osIndicationSupported should always be checked first. > + 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, => efi_guid_image_security_database > + 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, ditto for dbr -Takahiro Akashi > + 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: > -- > 2.17.1 >