From patchwork Thu Nov 18 07:03:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 1556481 X-Patchwork-Delegate: xypron.glpk@gmx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=z45cUZ6s; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HvrPf2JZpz9s1l for ; Thu, 18 Nov 2021 18:04:04 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id F226982A74; Thu, 18 Nov 2021 08:03:48 +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="z45cUZ6s"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 82D5182DF6; Thu, 18 Nov 2021 08:03:47 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) (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 5E17A81C08 for ; Thu, 18 Nov 2021 08:03:43 +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-ed1-x529.google.com with SMTP id r11so22480452edd.9 for ; Wed, 17 Nov 2021 23:03:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=WWjGVB4LfKNaZVtm8Rnm1MEILcUNBD5vYIP/s/t7JbI=; b=z45cUZ6s6mBNoGZ8LiyP4SbhcllmkpqWybL7kPi2w64w9aC8Ce4q6pIvcs45pA0wd0 nzuGrbCWQDfm5tJLdSt2EgpcYxxiF2aHjdKU5yxr0v4j1iyH6O3JQMxQzlRp0g65JzcQ iar05qvE24C+nkUp9RpGKDByVVl62khzDX8R43uMGve6B1dxQXQEhoKH85VD4R4FRYxx QYO1AXxsJtQPDm23RwQ2ACYK9QyGwzJ+7IEGfpRtmhfiOmOkJrRJ0seWvZMrESWXK3pG vGruNYPGnV8wdaiZBPl7+uwOEn5oXp1QZqYBClyp98pmrJ9W1daqbJvf6B9J4BoRsXJi D0LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=WWjGVB4LfKNaZVtm8Rnm1MEILcUNBD5vYIP/s/t7JbI=; b=1yHCyvkDhPv4w8Jbpl9idsctT+ThQjIa3aL0HDvgVir/b7ia5ypQ1jLv0PjAAa3Go0 EduawbSv2DsIP9AMh4BRjRXyZcaz2p+6ivtEDUkDzdDmmJCjA4WiVyoXY1olzK5EQu73 283XpVGZHUT7MfkjGfhKzYXMnvi839JrUqeT7Wr7nQ7borejek/8e3GwCoyUnAS3sUW4 TdkpYnKuR6T+s+8RiSZ0Qn/N6FE7/RC173w8OBXOURYKQE8nXNCP8MC4+zo3/u2ca7h2 /MinP1R70N4JLFNyrb18r50SmtTzS09bNEBhZE17AWZihfSukKgbowmc/ZJmRLpFVTGi cWvg== X-Gm-Message-State: AOAM532TFNTRkeGGZtOS8udJL8gX8YzV7LmO6dKK15tsoUHU3zZbzDiH Y6XeqQyWEA7rdR4rVpKPbAvCPA== X-Google-Smtp-Source: ABdhPJwq+q1DnVN3If+Dc9PeCpog4bt9UWO0HKAo3qkakIOsR9aJ6LGb39LTn/ju0bvWJeg1SkJMpA== X-Received: by 2002:a17:907:724f:: with SMTP id ds15mr29177877ejc.204.1637219022899; Wed, 17 Nov 2021 23:03:42 -0800 (PST) Received: from localhost.localdomain (ppp-94-66-220-79.home.otenet.gr. [94.66.220.79]) by smtp.gmail.com with ESMTPSA id e26sm1098578edr.82.2021.11.17.23.03.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Nov 2021 23:03:42 -0800 (PST) From: Ilias Apalodimas To: xypron.glpk@gmx.de Cc: Ilias Apalodimas , Alexander Graf , u-boot@lists.denx.de Subject: [PATCH v2] efi_loader: fix FinalEvents table if an EFI app invoked GetEventLog Date: Thu, 18 Nov 2021 09:03:39 +0200 Message-Id: <20211118070339.103342-1-ilias.apalodimas@linaro.org> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.35 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 As described in the TCG spec [1] in sections 7.1.1 and 7.1.2 the FinalEvent table should include events after GetEventLog has been called. This currently works for us as long as the kernel is the only EFI application calling that. Specifically we only implement what's described in 7.1.1. So refactor the code a bit and support EFI application(s) calling GetEventLog. Events will now be logged in both the EventLog and FinalEvent table as long as ExitBootServices haven't been invoked. [1] https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf Signed-off-by: Ilias Apalodimas --- changes since v1: - added documentation for the internal eventlog management struct lib/efi_loader/efi_tcg2.c | 99 +++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 29 deletions(-) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 189e4a5ba59c..9a36ba0f1568 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -27,6 +27,16 @@ #include #include +/* internal eventlog management struct + * + * @buffer: eventlog buffer + * @final_buffer: finalevent config table buffer + * @pos: current position of 'buffer' + * @final_pos: current position of 'final_buffer' + * @get_event_called: true if GetEventLog has been invoked at least once + * @ebs_called: true if ExitBootServices has been invoked + * @truncated: true if the 'buffer' is truncated + */ struct event_log_buffer { void *buffer; void *final_buffer; @@ -34,6 +44,7 @@ struct event_log_buffer { size_t final_pos; /* final events config table position */ size_t last_event_size; bool get_event_called; + bool ebs_called; bool truncated; }; @@ -186,39 +197,29 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, return EFI_SUCCESS; } -/* tcg2_agile_log_append - Append an agile event to out eventlog +/* put_event - Append an agile event to an eventlog * * @pcr_index: PCR index * @event_type: type of event added * @digest_list: list of digest algorithms to add * @size: size of event * @event: event to add + * @log: log buffer to append the event * - * @Return: status code */ -static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, - struct tpml_digest_values *digest_list, - u32 size, u8 event[]) +static void put_event(u32 pcr_index, u32 event_type, + struct tpml_digest_values *digest_list, u32 size, + u8 event[], void *log) { - void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos); size_t pos; size_t i; u32 event_size; - if (event_log.get_event_called) - log = (void *)((uintptr_t)event_log.final_buffer + - event_log.final_pos); - /* * size refers to the length of event[] only, we need to check against * the final tcg_pcr_event2 size */ event_size = size + tcg_event_final_size(digest_list); - if (event_log.pos + event_size > TPM2_EVENT_LOG_SIZE || - event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) { - event_log.truncated = true; - return EFI_VOLUME_FULL; - } put_unaligned_le32(pcr_index, log); pos = offsetof(struct tcg_pcr_event2, event_type); @@ -242,25 +243,63 @@ static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, memcpy((void *)((uintptr_t)log + pos), event, size); pos += size; - /* make sure the calculated buffer is what we checked against */ + /* + * make sure the calculated buffer is what we checked against + * This check should never fail. It checks the code above is + * calculating the right length for the event we are adding + * */ if (pos != event_size) - return EFI_INVALID_PARAMETER; + log_err("Appending to the EventLog failed\n"); - /* if GetEventLog hasn't been called update the normal log */ - if (!event_log.get_event_called) { - event_log.pos += pos; - event_log.last_event_size = pos; - } else { - /* if GetEventLog has been called update config table log */ - struct efi_tcg2_final_events_table *final_event; +} - final_event = - (struct efi_tcg2_final_events_table *)(event_log.final_buffer); - final_event->number_of_events++; - event_log.final_pos += pos; +/* tcg2_agile_log_append - Append an agile event to an eventlog + * + * @pcr_index: PCR index + * @event_type: type of event added + * @digest_list: list of digest algorithms to add + * @size: size of event + * @event: event to add + * @log: log buffer to append the event + * + * @Return: status code + */ +static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type, + struct tpml_digest_values *digest_list, + u32 size, u8 event[]) +{ + void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos); + u32 event_size = size + tcg_event_final_size(digest_list); + struct efi_tcg2_final_events_table *final_event; + efi_status_t ret = EFI_SUCCESS; + + /* if ExitBootServices hasn't been called update the normal log */ + if (!event_log.ebs_called) { + if (event_log.truncated || + event_log.pos + event_size > TPM2_EVENT_LOG_SIZE) { + event_log.truncated = true; + return EFI_VOLUME_FULL; + } + put_event(pcr_index, event_type, digest_list, size, event, log); + event_log.pos += event_size; + event_log.last_event_size = event_size; } - return EFI_SUCCESS; + if (!event_log.get_event_called) + return ret; + + /* if GetEventLog has been called update FinalEventLog as well */ + if (event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) + return EFI_VOLUME_FULL; + + log = (void *)((uintptr_t)event_log.final_buffer + event_log.final_pos); + put_event(pcr_index, event_type, digest_list, size, event, log); + + final_event = event_log.final_buffer; + final_event->number_of_events++; + event_log.final_pos += event_size; + + return ret; } /** @@ -1303,6 +1342,7 @@ static efi_status_t efi_init_event_log(void) event_log.pos = 0; event_log.last_event_size = 0; event_log.get_event_called = false; + event_log.ebs_called = false; event_log.truncated = false; /* @@ -1792,6 +1832,7 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context) EFI_ENTRY("%p, %p", event, context); + event_log.ebs_called = true; ret = platform_get_tpm2_device(&dev); if (ret != EFI_SUCCESS) goto out;