From patchwork Mon May 20 20:54:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10952347 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7C38D1395 for ; Mon, 20 May 2019 20:55:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6BB272871F for ; Mon, 20 May 2019 20:55:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5FFC32888C; Mon, 20 May 2019 20:55:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9F1BF288BB for ; Mon, 20 May 2019 20:55:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726893AbfETUzK (ORCPT ); Mon, 20 May 2019 16:55:10 -0400 Received: from mail-qt1-f201.google.com ([209.85.160.201]:37550 "EHLO mail-qt1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726857AbfETUzJ (ORCPT ); Mon, 20 May 2019 16:55:09 -0400 Received: by mail-qt1-f201.google.com with SMTP id q23so579458qtb.4 for ; Mon, 20 May 2019 13:55:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=akrm/3bgh71I70hR0K09l3Kfzzk0aIwNcfCkA5T1H8s=; b=YBpxht9kl8QYDiQ4NThsO65nDKncBg5XXpPzCNuHbT4kR7k7m0qx2/e6WdDmMsY2LY 2iLbS1wFLp6/bGp5FJa/Eo9+dJu1YFPAi9sl9XwAPRy5XI699M8FGgE45AOooLuweR6O gha7bK5+MQaJxFFeJAk3iPUZltWJVWxqBNLcjgfb3Cu7FLGAHh+Mgx61RYJGcEls3wcv ioK5P59ZLO4RWWuJe8gEgYB0SLYIr0S0drSe5DfqZ8oE9wDAy6Hq5siXjpUcd4nlvldz jmEdqpWaXcU0TJhsFdE6Jlqwynd771VjOkcgUnAoBRH14294GeufY8URUrFX2A7JYt4O sBXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=akrm/3bgh71I70hR0K09l3Kfzzk0aIwNcfCkA5T1H8s=; b=pwTE4GKjMSVRFM5IaVdKCl8gBMoBEHktqgAALA3XiE/pKhRQyuvdv+AzcwUe88zI28 5jpRCM00Fv1hbeU9niV2i0LAahODv5lDRg7N32y92VeaimlvH7cvwUQNBgHR8wTjV7kU UbUTxMN6Muiu0uZU4qhzHUGeyaOWveqmIiuRyQRiBcWKabdaekfEISh8clwvm873Vbnm 2Rb591QUpKmcJE5VpMv5+eUR+ZqTuZQ2KmbyI16xdB0c1aNSsOwzjpr88IMuv7xfACF/ u7vLmwUhZ02GT6gmAByMf6SRPkKYQ57vQKkZtVEBNvY/CgEg5nlNU/ebQk7CLcqiR2G+ 4XKQ== X-Gm-Message-State: APjAAAXq5CLuZluqF/ei6LDpvGPXYk3idLhmxG2dEGgohC2EV0aM36io +LmLOYfnp7Fe1SquebuT00kinQQG2ICOiw4kgnplEiuZiL0OqF/vCRtldhgIfBQJesNreLySs/P 8gpJPXGA+Hj4NR92A/nbZWzfy8Oz4dFjgcqHu+Gx+K5MPM0yMMrlKQGPgpb0YOmAAIgt3uWlxht FiK3Me450/uPzeH4FPB8w= X-Google-Smtp-Source: APXvYqzKTMYg8rW5jVfSQPhysQn7BFeOUlYvYPTcDiKFgnvWNRdEhRqy390LZ8ffPMPH9cPbWXbojWbOAP680fBQu19y3w== X-Received: by 2002:aed:21ca:: with SMTP id m10mr60246543qtc.97.1558385708444; Mon, 20 May 2019 13:55:08 -0700 (PDT) Date: Mon, 20 May 2019 13:54:58 -0700 In-Reply-To: <20190520205501.177637-1-matthewgarrett@google.com> Message-Id: <20190520205501.177637-2-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190520205501.177637-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog Subject: [PATCH V7 1/4] tpm: Abstract crypto agile event size calculations From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: peterhuewe@gmx.de, jarkko.sakkinen@linux.intel.com, jgg@ziepe.ca, roberto.sassu@huawei.com, linux-efi@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, tweek@google.com, bsz@semihalf.com, Matthew Garrett Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matthew Garrett We need to calculate the size of crypto agile events in multiple locations, including in the EFI boot stub. The easiest way to do this is to put it in a header file as an inline and leave a wrapper to ensure we don't end up with multiple copies of it embedded in the existing code. Signed-off-by: Matthew Garrett --- drivers/char/tpm/eventlog/tpm2.c | 47 +--------------------- include/linux/tpm_eventlog.h | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 46 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index f824563fc28d..1a977bdd3bd2 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c @@ -40,52 +40,7 @@ static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event, struct tcg_pcr_event *event_header) { - struct tcg_efi_specid_event_head *efispecid; - struct tcg_event_field *event_field; - void *marker; - void *marker_start; - u32 halg_size; - size_t size; - u16 halg; - int i; - int j; - - marker = event; - marker_start = marker; - marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type) - + sizeof(event->count); - - efispecid = (struct tcg_efi_specid_event_head *)event_header->event; - - /* Check if event is malformed. */ - if (event->count > efispecid->num_algs) - return 0; - - for (i = 0; i < event->count; i++) { - halg_size = sizeof(event->digests[i].alg_id); - memcpy(&halg, marker, halg_size); - marker = marker + halg_size; - for (j = 0; j < efispecid->num_algs; j++) { - if (halg == efispecid->digest_sizes[j].alg_id) { - marker += - efispecid->digest_sizes[j].digest_size; - break; - } - } - /* Algorithm without known length. Such event is unparseable. */ - if (j == efispecid->num_algs) - return 0; - } - - event_field = (struct tcg_event_field *)marker; - marker = marker + sizeof(event_field->event_size) - + event_field->event_size; - size = marker - marker_start; - - if ((event->event_type == 0) && (event_field->event_size == 0)) - return 0; - - return size; + return __calc_tpm2_event_size(event, event_header); } static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos) diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index 81519f163211..6a86144e13f1 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -112,4 +112,72 @@ struct tcg_pcr_event2_head { struct tpm_digest digests[]; } __packed; +/** + * __calc_tpm2_event_size - calculate the size of a TPM2 event log entry + * @event: Pointer to the event whose size should be calculated + * @event_header: Pointer to the initial event containing the digest lengths + * + * The TPM2 event log format can contain multiple digests corresponding to + * separate PCR banks, and also contains a variable length of the data that + * was measured. This requires knowledge of how long each digest type is, + * and this information is contained within the first event in the log. + * + * We calculate the length by examining the number of events, and then looking + * at each event in turn to determine how much space is used for events in + * total. Once we've done this we know the offset of the data length field, + * and can calculate the total size of the event. + * + * Return: size of the event on success, <0 on failure + */ + +static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, + struct tcg_pcr_event *event_header) +{ + struct tcg_efi_specid_event_head *efispecid; + struct tcg_event_field *event_field; + void *marker; + void *marker_start; + u32 halg_size; + size_t size; + u16 halg; + int i; + int j; + + marker = event; + marker_start = marker; + marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type) + + sizeof(event->count); + + efispecid = (struct tcg_efi_specid_event_head *)event_header->event; + + /* Check if event is malformed. */ + if (event->count > efispecid->num_algs) + return 0; + + for (i = 0; i < event->count; i++) { + halg_size = sizeof(event->digests[i].alg_id); + memcpy(&halg, marker, halg_size); + marker = marker + halg_size; + for (j = 0; j < efispecid->num_algs; j++) { + if (halg == efispecid->digest_sizes[j].alg_id) { + marker += + efispecid->digest_sizes[j].digest_size; + break; + } + } + /* Algorithm without known length. Such event is unparseable. */ + if (j == efispecid->num_algs) + return 0; + } + + event_field = (struct tcg_event_field *)marker; + marker = marker + sizeof(event_field->event_size) + + event_field->event_size; + size = marker - marker_start; + + if ((event->event_type == 0) && (event_field->event_size == 0)) + return 0; + + return size; +} #endif From patchwork Mon May 20 20:54:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10952335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7C70D14C0 for ; Mon, 20 May 2019 20:55:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 668122871F for ; Mon, 20 May 2019 20:55:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 58609288A7; Mon, 20 May 2019 20:55:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 706AF2871F for ; Mon, 20 May 2019 20:55:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726900AbfETUzM (ORCPT ); Mon, 20 May 2019 16:55:12 -0400 Received: from mail-yb1-f202.google.com ([209.85.219.202]:34617 "EHLO mail-yb1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726899AbfETUzM (ORCPT ); Mon, 20 May 2019 16:55:12 -0400 Received: by mail-yb1-f202.google.com with SMTP id b82so15370639yba.1 for ; Mon, 20 May 2019 13:55:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=50dwGxdTHi8Ised1JTOI9dboKsOH5Whl71pUdHfSJMU=; b=QNjIa5B16erbfN5TQvW/6pJr8gYAyYx/E5XNGC9ZVsIFvoLy+udkmVTxQfLBolwBgG rsXn/dKtbLhvgCK8Sm1xlRmtvbjd/Vw2ToRSj0E4mpCGbp9AdI/Befwwf97OjiukOwbf lMyj4/e7a/U2C40++didAimkCHvCi0UUIFh7j0VGJl48KgEZrdyDleUpSf6KoBer7YlG 3+fPs9zktMvEu93ghVNnsk2l3CiCzEdDAKspsWRpoUFKVbfNVrtqounQof1BOxqUzRxe 0PHw86ciGkhop59OvtpTQ5mj/QdVA0wMYcKkMamjMUu3+CWRU+pcdgRICyY+2fozGYyV 1brg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=50dwGxdTHi8Ised1JTOI9dboKsOH5Whl71pUdHfSJMU=; b=mV7pbc6tlKqQQIxQ/xc96AIRetTFKFzAB9/qlVplqnXV0HO6XathOlODPzPungLpF5 bsECS8Vy7XsPeF6GO5c8cQBcWVHr4KA6AgxOFqtZo9zS2csjAgdeJaXmJYH5FAeVwvtU cmcNLh+vRWEVLFtb03rgp0I/qjVDLcgAiT7CcXw31UN5l0usNtuOZSCcekZJHqEVSFIH kIJUjnLJUq25xyP8Wpb0Puw0HyB181Mk3xYZgjT5a2g2O1zY1Ow2BQjM7bTfCJArIhFp B23eoNFg4hI7MwC0jKEkJ/OfHmdv7RiUuJ6rswpr+8X8Alb0ZY1S0z38cBnk1bWtYXId 8ZjA== X-Gm-Message-State: APjAAAWybfLmIzQSushbfB/AY3+VQcJICU9C2CQ9X9ex+MYXTIwkJu9x DBA6q09VTe1vX2xYgLakVG9LTh7kaFo9L3zlp4biXKhOwTkRBbSWECWvgVR/AUq3KMltv2tc7WE maOCHOWWvLCgsOoBMWMWG/3kfBZN0QAUICcDBX+odhR5ALH9UC2BxRlDP7ggF1x7IrYRR2LmCpX 22ryCoVZTgl7zmxxFe+cg= X-Google-Smtp-Source: APXvYqyXc6osaai1XOWM158uZ/v1yIQke6ji+PQ/RHbUx11AJhRE4zuLcpDsxOoN/0EKeVwgYJXuWqLLuKb6gUIKgKxiEg== X-Received: by 2002:a81:9a0e:: with SMTP id r14mr36701712ywg.496.1558385711030; Mon, 20 May 2019 13:55:11 -0700 (PDT) Date: Mon, 20 May 2019 13:54:59 -0700 In-Reply-To: <20190520205501.177637-1-matthewgarrett@google.com> Message-Id: <20190520205501.177637-3-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190520205501.177637-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog Subject: [PATCH V7 2/4] tpm: Reserve the TPM final events table From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: peterhuewe@gmx.de, jarkko.sakkinen@linux.intel.com, jgg@ziepe.ca, roberto.sassu@huawei.com, linux-efi@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, tweek@google.com, bsz@semihalf.com, Matthew Garrett Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matthew Garrett UEFI systems provide a boot services protocol for obtaining the TPM event log, but this is unusable after ExitBootServices() is called. Unfortunately ExitBootServices() itself triggers additional TPM events that then can't be obtained using this protocol. The platform provides a mechanism for the OS to obtain these events by recording them to a separate UEFI configuration table which the OS can then map. Unfortunately this table isn't self describing in terms of providing its length, so we need to parse the events inside it to figure out how long it is. Since the table isn't mapped at this point, we need to extend the length calculation function to be able to map the event as it goes along. (Fixes by Bartosz Szczepanek ) Signed-off-by: Matthew Garrett Acked-by: Ard Biesheuvel --- drivers/char/tpm/eventlog/tpm2.c | 2 +- drivers/firmware/efi/efi.c | 2 + drivers/firmware/efi/tpm.c | 62 ++++++++++++++++++- include/linux/efi.h | 9 +++ include/linux/tpm_eventlog.h | 102 ++++++++++++++++++++++++++++--- 5 files changed, 164 insertions(+), 13 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index 1a977bdd3bd2..de1d9f7e5a92 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c @@ -40,7 +40,7 @@ static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event, struct tcg_pcr_event *event_header) { - return __calc_tpm2_event_size(event, event_header); + return __calc_tpm2_event_size(event, event_header, false); } static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos) diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 55b77c576c42..6b11c41e0575 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -53,6 +53,7 @@ struct efi __read_mostly efi = { .mem_attr_table = EFI_INVALID_TABLE_ADDR, .rng_seed = EFI_INVALID_TABLE_ADDR, .tpm_log = EFI_INVALID_TABLE_ADDR, + .tpm_final_log = EFI_INVALID_TABLE_ADDR, .mem_reserve = EFI_INVALID_TABLE_ADDR, }; EXPORT_SYMBOL(efi); @@ -485,6 +486,7 @@ static __initdata efi_config_table_type_t common_tables[] = { {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table}, {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed}, {LINUX_EFI_TPM_EVENT_LOG_GUID, "TPMEventLog", &efi.tpm_log}, + {LINUX_EFI_TPM_FINAL_LOG_GUID, "TPMFinalLog", &efi.tpm_final_log}, {LINUX_EFI_MEMRESERVE_TABLE_GUID, "MEMRESERVE", &efi.mem_reserve}, {NULL_GUID, NULL, NULL}, }; diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c index 3a689b40ccc0..2c912ea08166 100644 --- a/drivers/firmware/efi/tpm.c +++ b/drivers/firmware/efi/tpm.c @@ -4,34 +4,90 @@ * Thiebaud Weksteen */ +#define TPM_MEMREMAP(start, size) early_memremap(start, size) +#define TPM_MEMUNMAP(start, size) early_memunmap(start, size) + #include #include #include +#include #include +int efi_tpm_final_log_size; +EXPORT_SYMBOL(efi_tpm_final_log_size); + +static int tpm2_calc_event_log_size(void *data, int count, void *size_info) +{ + struct tcg_pcr_event2_head *header; + int event_size, size = 0; + + while (count > 0) { + header = data + size; + event_size = __calc_tpm2_event_size(header, size_info, true); + if (event_size == 0) + return -1; + size += event_size; + count--; + } + + return size; +} + /* * Reserve the memory associated with the TPM Event Log configuration table. */ int __init efi_tpm_eventlog_init(void) { struct linux_efi_tpm_eventlog *log_tbl; + struct efi_tcg2_final_events_table *final_tbl; unsigned int tbl_size; + int ret = 0; - if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) + if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) { + /* + * We can't calculate the size of the final events without the + * first entry in the TPM log, so bail here. + */ return 0; + } log_tbl = early_memremap(efi.tpm_log, sizeof(*log_tbl)); if (!log_tbl) { pr_err("Failed to map TPM Event Log table @ 0x%lx\n", - efi.tpm_log); + efi.tpm_log); efi.tpm_log = EFI_INVALID_TABLE_ADDR; return -ENOMEM; } tbl_size = sizeof(*log_tbl) + log_tbl->size; memblock_reserve(efi.tpm_log, tbl_size); + + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) + goto out; + + final_tbl = early_memremap(efi.tpm_final_log, sizeof(*final_tbl)); + + if (!final_tbl) { + pr_err("Failed to map TPM Final Event Log table @ 0x%lx\n", + efi.tpm_final_log); + efi.tpm_final_log = EFI_INVALID_TABLE_ADDR; + ret = -ENOMEM; + goto out; + } + + tbl_size = tpm2_calc_event_log_size(efi.tpm_final_log + + sizeof(final_tbl->version) + + sizeof(final_tbl->nr_events), + final_tbl->nr_events, + log_tbl->log); + memblock_reserve((unsigned long)final_tbl, + tbl_size + sizeof(*final_tbl)); + early_memunmap(final_tbl, sizeof(*final_tbl)); + efi_tpm_final_log_size = tbl_size; + +out: early_memunmap(log_tbl, sizeof(*log_tbl)); - return 0; + return ret; } diff --git a/include/linux/efi.h b/include/linux/efi.h index 54357a258b35..e33c70a52a9d 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -689,6 +689,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) #define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa) +#define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25) #define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2) typedef struct { @@ -996,6 +997,7 @@ extern struct efi { unsigned long mem_attr_table; /* memory attributes table */ unsigned long rng_seed; /* UEFI firmware random seed */ unsigned long tpm_log; /* TPM2 Event Log table */ + unsigned long tpm_final_log; /* TPM2 Final Events Log table */ unsigned long mem_reserve; /* Linux EFI memreserve table */ efi_get_time_t *get_time; efi_set_time_t *set_time; @@ -1707,6 +1709,13 @@ struct linux_efi_tpm_eventlog { extern int efi_tpm_eventlog_init(void); +struct efi_tcg2_final_events_table { + u64 version; + u64 nr_events; + u8 events[]; +}; +extern int efi_tpm_final_log_size; + /* * efi_runtime_service() function identifiers. * "NONE" is used by efi_recover_from_page_fault() to check if the page diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index 6a86144e13f1..63238c84dc0b 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -112,10 +112,35 @@ struct tcg_pcr_event2_head { struct tpm_digest digests[]; } __packed; +struct tcg_algorithm_size { + u16 algorithm_id; + u16 algorithm_size; +}; + +struct tcg_algorithm_info { + u8 signature[16]; + u32 platform_class; + u8 spec_version_minor; + u8 spec_version_major; + u8 spec_errata; + u8 uintn_size; + u32 number_of_algorithms; + struct tcg_algorithm_size digest_sizes[]; +}; + +#ifndef TPM_MEMREMAP +#define TPM_MEMREMAP(start, size) NULL +#endif + +#ifndef TPM_MEMUNMAP +#define TPM_MEMUNMAP(start, size) do{} while(0) +#endif + /** * __calc_tpm2_event_size - calculate the size of a TPM2 event log entry * @event: Pointer to the event whose size should be calculated * @event_header: Pointer to the initial event containing the digest lengths + * @do_mapping: Whether or not the event needs to be mapped * * The TPM2 event log format can contain multiple digests corresponding to * separate PCR banks, and also contains a variable length of the data that @@ -131,10 +156,13 @@ struct tcg_pcr_event2_head { */ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, - struct tcg_pcr_event *event_header) + struct tcg_pcr_event *event_header, + bool do_mapping) { struct tcg_efi_specid_event_head *efispecid; struct tcg_event_field *event_field; + void *mapping = NULL; + int mapping_size; void *marker; void *marker_start; u32 halg_size; @@ -148,16 +176,49 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type) + sizeof(event->count); + /* Map the event header */ + if (do_mapping) { + mapping_size = marker - marker_start; + mapping = TPM_MEMREMAP((unsigned long)marker_start, + mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } else { + mapping = marker_start; + } + + event = (struct tcg_pcr_event2_head *)mapping; + efispecid = (struct tcg_efi_specid_event_head *)event_header->event; /* Check if event is malformed. */ - if (event->count > efispecid->num_algs) - return 0; + if (event->count > efispecid->num_algs) { + size = 0; + goto out; + } for (i = 0; i < event->count; i++) { halg_size = sizeof(event->digests[i].alg_id); - memcpy(&halg, marker, halg_size); + + /* Map the digest's algorithm identifier */ + if (do_mapping) { + TPM_MEMUNMAP(mapping, mapping_size); + mapping_size = halg_size; + mapping = TPM_MEMREMAP((unsigned long)marker, + mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } else { + mapping = marker; + } + + memcpy(&halg, mapping, halg_size); marker = marker + halg_size; + for (j = 0; j < efispecid->num_algs; j++) { if (halg == efispecid->digest_sizes[j].alg_id) { marker += @@ -166,18 +227,41 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, } } /* Algorithm without known length. Such event is unparseable. */ - if (j == efispecid->num_algs) - return 0; + if (j == efispecid->num_algs) { + size = 0; + goto out; + } + } + + /* + * Map the event size - we don't read from the event itself, so + * we don't need to map it + */ + if (do_mapping) { + TPM_MEMUNMAP(mapping, mapping_size); + mapping_size += sizeof(event_field->event_size); + mapping = TPM_MEMREMAP((unsigned long)marker, + mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } else { + mapping = marker; } - event_field = (struct tcg_event_field *)marker; + event_field = (struct tcg_event_field *)mapping; + marker = marker + sizeof(event_field->event_size) + event_field->event_size; size = marker - marker_start; if ((event->event_type == 0) && (event_field->event_size == 0)) - return 0; - + size = 0; +out: + if (do_mapping) + TPM_MEMUNMAP(mapping, mapping_size); return size; } + #endif From patchwork Mon May 20 20:55:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10952345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C7C5F1708 for ; Mon, 20 May 2019 20:55:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B90A02871F for ; Mon, 20 May 2019 20:55:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AD6DB28896; Mon, 20 May 2019 20:55:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E1E32888C for ; Mon, 20 May 2019 20:55:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726939AbfETUzX (ORCPT ); Mon, 20 May 2019 16:55:23 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:36776 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726935AbfETUzO (ORCPT ); Mon, 20 May 2019 16:55:14 -0400 Received: by mail-pg1-f201.google.com with SMTP id d5so10540427pga.3 for ; Mon, 20 May 2019 13:55:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=aAD72H50ABa7i4hUmGTaWeMcxOGiBgmrF/zB0iTqZPc=; b=oy4ecePBsvz9xac0sPq5+vZj/9DPsHi82imiGV3JXteI2ZIAgaQBj5lIBG6QRT7Pwb JDCFVI8HELF3U8vUxaYayffHsPJmwS+V5pA5EM0kHV+BtF5CrZDr8WKsebDQKfJePJ1U VRp5JL+s0h20lcmBB9keY28+iGuLquVMetdMhqk5NzKXJUjlIb5UWHt3tBEefJ4BVQZk EqPYQ9dO7jAmi2kUrMfB6cGrkhG7Hy27QAJ7NphhR2soj/A+Ae1hUeh3RrBSbnyaZShU OICSHoL+cttN6/XUpBvv0K3X3GLs1y0aS/M7lZHBvclCcp61I0eQv8ZJjpJMeZTDaPVV UW3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=aAD72H50ABa7i4hUmGTaWeMcxOGiBgmrF/zB0iTqZPc=; b=pPRHSOYe4AJ/13nce2wXVUVOgCuLltdWktoxbrNeB3psJKVHqEXDgrLPlqf16cRKK4 mbzCjTcHQFNyQd8loX+Cr6uJ/WN0PTJdrWipP4BNSqLOEYvrgCVvJWYPspbF4G13nvtl 7okiyhBwimFUVDS/f8jBCs2Js1ICrH25tVH4EbKa95vX3aKWq5y0T9eP4GeqS0//QrhU WVFmnaxxdn5cbZOWhgTeXhGxxLGSA16Mtdlnnhx5p6vvR0zgfsxbeQJXRabbBKFZjye0 zk2AJ+s49npHrgwqsd1ze27fbBIiBwTO+Qew/LPBwIlzixOMATTqgNJkWssXXvPz8NgX TILQ== X-Gm-Message-State: APjAAAX0kD8wb8sZcOkwjZ/52M3dbpAUbZI/VQuHjXMKV26yzd6M2qUr B1Rv4F5/479HFqYnF7sEavFT5mR6CRXg1Amh2QC2N+4CXcO3EmvEd6vHgGA8ipEVOUZKRGTCJEN mJP6guE4mlwp4Fxo9ebYPNq+a8RnLxY+R9341ReWEb35Hp8uHe8U8NJvSZl/zoc7qB7hlRbiYim 47rcwk6choEqVAYSXYKJo= X-Google-Smtp-Source: APXvYqx75zjpUcQWvw9WxMc9l5hCExHXJMIe9nadtcG8JTTEN8h5aDc/zRJjwAMciCjy8pxxh8N9mOQ4lXQ6Ys5tGDb96g== X-Received: by 2002:a65:4c07:: with SMTP id u7mr75208395pgq.93.1558385713378; Mon, 20 May 2019 13:55:13 -0700 (PDT) Date: Mon, 20 May 2019 13:55:00 -0700 In-Reply-To: <20190520205501.177637-1-matthewgarrett@google.com> Message-Id: <20190520205501.177637-4-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190520205501.177637-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog Subject: [PATCH V7 3/4] tpm: Append the final event log to the TPM event log From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: peterhuewe@gmx.de, jarkko.sakkinen@linux.intel.com, jgg@ziepe.ca, roberto.sassu@huawei.com, linux-efi@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, tweek@google.com, bsz@semihalf.com, Matthew Garrett Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matthew Garrett Any events that are logged after GetEventsLog() is called are logged to the EFI Final Events table. These events are defined as being in the crypto agile log format, so we can just append them directly to the existing log if it's in the same format. In theory we can also construct old-style SHA1 log entries for devices that only return logs in that format, but EDK2 doesn't generate the final event log in that case so it doesn't seem worth it at the moment. Signed-off-by: Matthew Garrett --- drivers/char/tpm/eventlog/efi.c | 50 ++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/char/tpm/eventlog/efi.c b/drivers/char/tpm/eventlog/efi.c index 3e673ab22cb4..9179cf6bdee9 100644 --- a/drivers/char/tpm/eventlog/efi.c +++ b/drivers/char/tpm/eventlog/efi.c @@ -21,10 +21,13 @@ int tpm_read_log_efi(struct tpm_chip *chip) { + struct efi_tcg2_final_events_table *final_tbl = NULL; struct linux_efi_tpm_eventlog *log_tbl; struct tpm_bios_log *log; u32 log_size; u8 tpm_log_version; + void *tmp; + int ret; if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) return -ENODEV; @@ -52,15 +55,48 @@ int tpm_read_log_efi(struct tpm_chip *chip) /* malloc EventLog space */ log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL); - if (!log->bios_event_log) - goto err_memunmap; - log->bios_event_log_end = log->bios_event_log + log_size; + if (!log->bios_event_log) { + ret = -ENOMEM; + goto out; + } + log->bios_event_log_end = log->bios_event_log + log_size; tpm_log_version = log_tbl->version; - memunmap(log_tbl); - return tpm_log_version; -err_memunmap: + ret = tpm_log_version; + + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || + efi_tpm_final_log_size == 0 || + tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + goto out; + + final_tbl = memremap(efi.tpm_final_log, + sizeof(*final_tbl) + efi_tpm_final_log_size, + MEMREMAP_WB); + if (!final_tbl) { + pr_err("Could not map UEFI TPM final log\n"); + kfree(log->bios_event_log); + ret = -ENOMEM; + goto out; + } + + tmp = krealloc(log->bios_event_log, + log_size + efi_tpm_final_log_size, + GFP_KERNEL); + if (!tmp) { + kfree(log->bios_event_log); + ret = -ENOMEM; + goto out; + } + + log->bios_event_log = tmp; + memcpy((void *)log->bios_event_log + log_size, + final_tbl->events, efi_tpm_final_log_size); + log->bios_event_log_end = log->bios_event_log + + log_size + efi_tpm_final_log_size; + +out: + memunmap(final_tbl); memunmap(log_tbl); - return -ENOMEM; + return ret; } From patchwork Mon May 20 20:55:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10952339 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 992DC1395 for ; Mon, 20 May 2019 20:55:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 87F742871F for ; Mon, 20 May 2019 20:55:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7C43528896; Mon, 20 May 2019 20:55:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0B5A82871F for ; Mon, 20 May 2019 20:55:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726990AbfETUzS (ORCPT ); Mon, 20 May 2019 16:55:18 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:56991 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726979AbfETUzQ (ORCPT ); Mon, 20 May 2019 16:55:16 -0400 Received: by mail-pg1-f202.google.com with SMTP id r191so7454474pgr.23 for ; Mon, 20 May 2019 13:55:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=2S/gHsQaO08L1k/kaLAgP/iaI6c/d06OZBDkdH1Ekx0=; b=bn7WHiENp+Jgwq76sRokv6v0WVMG7P/MdlQ0xYiJJeuGCup45bH514LUOM4BaBFOuw hIy6lnvtRfymw2xIt/dCmLB5QS6fGxTOlZYBEXpo0fOw05p1vzBfpNRMnKilxoy8UJmN RundMf4Zidiv5pdMqiDJvIqlfmZe4p5XNL2Bn1ZR7Dqmvkh6yYJEVYefZZAvfG0DAdhn WVNDbeYz1YoQ3AbvTdCoacQlkFj8rWvYmubnWoAplDxM0LIxIKMh5grd4dEY/YsLNvRf rvu7FgRa2sS22ddDAmespjdjtj/wHQO2czYud2euSGrg99uYS6zQvwMyGrquZxSrhL+P d4xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=2S/gHsQaO08L1k/kaLAgP/iaI6c/d06OZBDkdH1Ekx0=; b=nSgMg807v/T2sG55+KtHNgSGpOOEFa1gdfzqp5xUCfSC5nI8hYL/y+2Cuxo2Y97Xb7 OhhuCUJoB23gXwAE0pCBX5s0yJJvow+J4q2nNS7S5rbj94dRHWRZGpiIrV01ysf099fA +YacNoD6+VPtsjbfEk46prJl9Ra23AMHUU2mXXRAyux38RGitj9m423siMWncuM0ftpW BcTKIGQKMKvXE1PMhd4/Oau1QoJfZ/YFXTiQszUVmzjLGmKaHD2QZkq+384RXOLh4HvF j1etspMMmPTWHjNlGQ0YzGgM2kdbze+OJ1+LxhZDaRpCRJDlqFjzYVnnfxer8+0PYIwK idwQ== X-Gm-Message-State: APjAAAU5urIyxv7toDgjUHUeWXJzWTX4A7UhaTNrxquOpwTERV4pCxgF CD3Tc6X/rRTpCG5B8utIGHjgrCua+BTKmLlIEjQW1zBvS8nzALxpqi95LnRYl7PEeo/q5l6XVNc 5YLSXSv/qk4xYEMOx6Q7oO+G2Fd2VUpAgIcgV+paUGX4p60dDsxwkKi7acAaJ8pqnVvF6WqcB/i HRD0GFr9un0/VCmaSeFyA= X-Google-Smtp-Source: APXvYqzXluYerRenEIporaBqlL0VKRUEYZ6bb//DTlFcuJIwvPvXL8WLmsndEpl+oa5KGu6dGG7EK4vv+klAAzBgskcu3w== X-Received: by 2002:a63:1061:: with SMTP id 33mr51272273pgq.328.1558385715691; Mon, 20 May 2019 13:55:15 -0700 (PDT) Date: Mon, 20 May 2019 13:55:01 -0700 In-Reply-To: <20190520205501.177637-1-matthewgarrett@google.com> Message-Id: <20190520205501.177637-5-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190520205501.177637-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog Subject: [PATCH V7 4/4] efi: Attempt to get the TCG2 event log in the boot stub From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: peterhuewe@gmx.de, jarkko.sakkinen@linux.intel.com, jgg@ziepe.ca, roberto.sassu@huawei.com, linux-efi@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, tweek@google.com, bsz@semihalf.com, Matthew Garrett Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matthew Garrett Right now we only attempt to obtain the SHA1-only event log. The protocol also supports a crypto agile log format, which contains digests for all algorithms in use. Attempt to obtain this first, and fall back to obtaining the older format if the system doesn't support it. This is lightly complicated by the event sizes being variable (as we don't know in advance which algorithms are in use), and the interface giving us back a pointer to the start of the final entry rather than a pointer to the end of the log - as a result, we need to parse the final entry to figure out its length in order to know how much data to copy up to the OS. Signed-off-by: Matthew Garrett Acked-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/tpm.c | 50 ++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c index 5bd04f75d8d6..6b3b507a54eb 100644 --- a/drivers/firmware/efi/libstub/tpm.c +++ b/drivers/firmware/efi/libstub/tpm.c @@ -57,7 +57,7 @@ void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) #endif -static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) +void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg) { efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID; @@ -67,6 +67,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) unsigned long first_entry_addr, last_entry_addr; size_t log_size, last_entry_size; efi_bool_t truncated; + int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; void *tcg2_protocol = NULL; status = efi_call_early(locate_protocol, &tcg2_guid, NULL, @@ -74,14 +75,20 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) if (status != EFI_SUCCESS) return; - status = efi_call_proto(efi_tcg2_protocol, get_event_log, tcg2_protocol, - EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, - &log_location, &log_last_entry, &truncated); - if (status != EFI_SUCCESS) - return; + status = efi_call_proto(efi_tcg2_protocol, get_event_log, + tcg2_protocol, version, &log_location, + &log_last_entry, &truncated); + + if (status != EFI_SUCCESS || !log_location) { + version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; + status = efi_call_proto(efi_tcg2_protocol, get_event_log, + tcg2_protocol, version, &log_location, + &log_last_entry, &truncated); + if (status != EFI_SUCCESS || !log_location) + return; + + } - if (!log_location) - return; first_entry_addr = (unsigned long) log_location; /* @@ -96,8 +103,23 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) * We need to calculate its size to deduce the full size of * the logs. */ - last_entry_size = sizeof(struct tcpa_event) + - ((struct tcpa_event *) last_entry_addr)->event_size; + if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { + /* + * The TCG2 log format has variable length entries, + * and the information to decode the hash algorithms + * back into a size is contained in the first entry - + * pass a pointer to the final entry (to calculate its + * size) and the first entry (so we know how long each + * digest is) + */ + last_entry_size = + __calc_tpm2_event_size((void *)last_entry_addr, + (void *)(long)log_location, + false); + } else { + last_entry_size = sizeof(struct tcpa_event) + + ((struct tcpa_event *) last_entry_addr)->event_size; + } log_size = log_last_entry - log_location + last_entry_size; } @@ -114,7 +136,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) memset(log_tbl, 0, sizeof(*log_tbl) + log_size); log_tbl->size = log_size; - log_tbl->version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; + log_tbl->version = version; memcpy(log_tbl->log, (void *) first_entry_addr, log_size); status = efi_call_early(install_configuration_table, @@ -126,9 +148,3 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) err_free: efi_call_early(free_pool, log_tbl); } - -void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg) -{ - /* Only try to retrieve the logs in 1.2 format. */ - efi_retrieve_tpm2_eventlog_1_2(sys_table_arg); -}