From patchwork Wed Jan 9 01:48:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10753349 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 18FD96C5 for ; Wed, 9 Jan 2019 01:48:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06BB528672 for ; Wed, 9 Jan 2019 01:48:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF15B2880A; Wed, 9 Jan 2019 01:48:57 +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 87CB728672 for ; Wed, 9 Jan 2019 01:48:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729144AbfAIBs5 (ORCPT ); Tue, 8 Jan 2019 20:48:57 -0500 Received: from mail-qt1-f202.google.com ([209.85.160.202]:34610 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729102AbfAIBs5 (ORCPT ); Tue, 8 Jan 2019 20:48:57 -0500 Received: by mail-qt1-f202.google.com with SMTP id u32so5313755qte.1 for ; Tue, 08 Jan 2019 17:48:56 -0800 (PST) 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=iol3z4VOW6917X90lpq+9GvwFXobBSIwuijvJwU/GVo=; b=KCqR6TYXjFqRpGjBAsfCsCHHiCt/FmvaaXBEEktkQG0/DhjzS326uQkpcgIS7caAQ2 JztROdy8xB1o7xOWvuN42IjrVubpjFR4SQpOtVdMVt5XPYCpa5oE/6tWCATdJsjbriBJ jkuvHkDPyTeTIys6KuDSUfqXyGJ5kV50LUgCx6EQM2pXHf55Cx3sZax4HOaRzgBBx2KI bTrMiqiZdN8tcSemVINTDMADJIneIMLaNFhJAd4XHyiwPk588X/zXj//O+8hTd0uXBqI fzgylC8Df4Azu/aRtTg5nVZ/fHJc+khR3ynRVsbc5ux8aEPhENVtyP0hMuISCnJ129hM PDSg== 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=iol3z4VOW6917X90lpq+9GvwFXobBSIwuijvJwU/GVo=; b=CkyS4oVwsAtLQDfJkI7jjC2F6IYeNZw0kVs2bSIvpRf4weThhM9MzPTA0ANgaezOPW c/hFRUhoAqEo6gWulPYtYaIwpkP+cEi58jwvfq9DONiw9QsBZh5RAvRuBSvSH7BJ5K58 +j3nClxQxjcid8WD06J5aVC/nTaQy2PDPdlhRGXHlONShrzulvHgZR+GxZFIhQOY7z4u 7te1/K9o7SMp6yP1aJpzFmi6qZLyg0RddKjxUqskp9DcGzxEGDv0Gd9uS5PgdFmXfr9P zFAHyoOYET+V8MutjvA7vGSwCY/nggi7b0gPjXauJ5SygfO0j/79MITETfzwjXFAWH2G T9TQ== X-Gm-Message-State: AJcUukfByCWo4xv7i+c5NcXvVMXosxaYDVGnW7JMbqIpfjPORJaijvli KIaVtJjRHz9iISoci6YpXAh7ZZ137UnQRYhvw8/I8uee8o/a6Gwd44mRlGQFBiJEschwrSSrk4t lq/L+/VhCF/IalE1GqNJoKN97hIT8XNLTKniWHXYRbEKCouFEQr1VuGLpqURf98i+dPs91Awddt 6PHBxhSvsnNL5phRv6eYY= X-Google-Smtp-Source: ALg8bN62irfTJAzi0Ay4cuOV3WevwHkNima9DTUXkDKTgn5aQwBYD0yHDuvCEzEb9goDaCF82fIcWvJlyNsq31y0CYjezA== X-Received: by 2002:a37:d4d4:: with SMTP id s81mr2767451qks.34.1546998535876; Tue, 08 Jan 2019 17:48:55 -0800 (PST) Date: Tue, 8 Jan 2019 17:48:43 -0800 In-Reply-To: <20190109014847.39980-1-matthewgarrett@google.com> Message-Id: <20190109014847.39980-2-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190109014847.39980-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.20.1.97.g81188d93c3-goog Subject: [PATCH 1/5] 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, 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 | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index 1b8fa9de2cac..5023f7f284ef 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c @@ -40,52 +40,7 @@ static int calc_tpm2_event_size(struct tcg_pcr_event2 *event, struct tcg_pcr_event *event_header) { - struct tcg_efi_specid_event *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 *)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 20d9da77fc11..b43bd2ea8bab 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -121,4 +121,54 @@ struct tcg_pcr_event2 { struct tcg_event_field event; } __packed; +static inline int _calc_tpm2_event_size(struct tcg_pcr_event2 *event, + struct tcg_pcr_event *event_header) +{ + struct tcg_efi_specid_event *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 *)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 Wed Jan 9 01:48:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10753351 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 80F5D91E for ; Wed, 9 Jan 2019 01:49:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6F4FE28672 for ; Wed, 9 Jan 2019 01:49:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 63B15287C0; Wed, 9 Jan 2019 01:49:00 +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 C74FA28672 for ; Wed, 9 Jan 2019 01:48:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729184AbfAIBs7 (ORCPT ); Tue, 8 Jan 2019 20:48:59 -0500 Received: from mail-it1-f201.google.com ([209.85.166.201]:38420 "EHLO mail-it1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729102AbfAIBs7 (ORCPT ); Tue, 8 Jan 2019 20:48:59 -0500 Received: by mail-it1-f201.google.com with SMTP id m128so5671268itd.3 for ; Tue, 08 Jan 2019 17:48:58 -0800 (PST) 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=DxFYq024RVahqsE1uVuvS4sennzmufeMEdvNHXpV1Oc=; b=k2ZP30NCH1/Y0TGsgterb+QaUKKqR10YxI5Ny4VmLRkUfL5dcpujqU3snzMejNldRn oBturH2r4W2GJvjBK3TJtHAHjFDRGR37VBPadjxwjIKENjI8pswfZGjdOfr0uYTndQmw U73MJDj8Q1mj+BmkB/xvUU6Pn6p+RTWitMjB3xHWSW7eUlWusLw9rfofbwZz7IB4iXkJ DfxnGxAR6PbLtyBvF3KGmzULfz2ZqMAMvQtsu5uAPR0ny5+d5gXsYKlyPkmoMh1bTZJc 3atiWgqlOELNOjjBCePRXqIBxFm9RsknBqdyO5QzZx+4/lPmA+79VurVmFLHaH5CzLSb Goqw== 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=DxFYq024RVahqsE1uVuvS4sennzmufeMEdvNHXpV1Oc=; b=kaRszFP56JvwqFBc9onlJ/U+NLOFoG5Q/i8Gc3ntZZ4EvvPSDMzgWm8+eCZcOamwzG 5yJoivbJ0InU38vBswCdAZReVvFO1J0CwkrvGka/uGCAIZ81xlRPGNhc3jKRqDSlpQuI U+tCcyw0SKrsi/kl+elgh+BR01Re1vlc4IF0wlMCpB/sn2TM+pCBBoPiJ3gQM8+dFuEo DWYyQmwk3gbUhi3VjDfyS2akgU6/gMnhO7IHGzAThn10bhCxDmyxug8+KFMSxVgmKY83 VB/mfQPZE5HyYqlgxrIrBHq3mtAoMGoZ9BgHRKYjYk4XrFfa/Tw0FtrCjxlN+W0xak06 vOqQ== X-Gm-Message-State: AJcUukduLehubSHB26gvOtV+neJDUePm1FF8LFlI1k5DwN3+gEmGMlDU 30gflYFAC/gT+njEqbB303zQSpd3Xav9Cy/ieLUmFMWI/HvaNnORKNCJ3w7eO53+dvqvpwX/TvY M5jurvnwNGHgdcXuSx/FqwAZ+mLNtn+D4NAhrviRZgTQ+irBN0mGGKgBVBftwQ22hT1TZJRiPq+ d22TcM8IpEgZ0bOltQxkQ= X-Google-Smtp-Source: ALg8bN4MuayjFpFxxcD7f5Gqz2Zq+qfOQkV37We+G8sWhkvb2GKTP+J7dzM6LMgrr4hYWwMe/O/qljrd2PRJ7YY5LBay7g== X-Received: by 2002:a24:594f:: with SMTP id p76mr3123699itb.10.1546998538121; Tue, 08 Jan 2019 17:48:58 -0800 (PST) Date: Tue, 8 Jan 2019 17:48:44 -0800 In-Reply-To: <20190109014847.39980-1-matthewgarrett@google.com> Message-Id: <20190109014847.39980-3-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190109014847.39980-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.20.1.97.g81188d93c3-goog Subject: [PATCH 2/5] tpm: Fix event log types for TPM2 From: Matthew Garrett To: linux-integrity@vger.kernel.org Cc: peterhuewe@gmx.de, jarkko.sakkinen@linux.intel.com, jgg@ziepe.ca, 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 These structs are defined as having variable length members, not fixed size ones. Fix that up and rename them to more accurately describe the only safe way they can be used, and fix the code that relied on having fixed structures. Signed-off-by: Matthew Garrett --- drivers/char/tpm/eventlog/tpm2.c | 8 ++++---- drivers/char/tpm/tpm-interface.c | 32 ++++++++++++++++++++++++-------- drivers/char/tpm/tpm.h | 3 ++- drivers/char/tpm/tpm2-cmd.c | 15 ++++++++++++++- include/linux/tpm_eventlog.h | 27 +++++++++++++++++++++------ 5 files changed, 65 insertions(+), 20 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index 5023f7f284ef..1343179c0a0e 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c @@ -37,7 +37,7 @@ * * Returns size of the event. If it is an invalid event, returns 0. */ -static int calc_tpm2_event_size(struct tcg_pcr_event2 *event, +static int calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event, struct tcg_pcr_event *event_header) { return _calc_tpm2_event_size(event, event_header); @@ -50,7 +50,7 @@ static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos) void *addr = log->bios_event_log; void *limit = log->bios_event_log_end; struct tcg_pcr_event *event_header; - struct tcg_pcr_event2 *event; + struct tcg_pcr_event2_hdr *event; size_t size; int i; @@ -91,7 +91,7 @@ static void *tpm2_bios_measurements_next(struct seq_file *m, void *v, loff_t *pos) { struct tcg_pcr_event *event_header; - struct tcg_pcr_event2 *event; + struct tcg_pcr_event2_hdr *event; struct tpm_chip *chip = m->private; struct tpm_bios_log *log = &chip->log; void *limit = log->bios_event_log_end; @@ -135,7 +135,7 @@ static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v) struct tpm_chip *chip = m->private; struct tpm_bios_log *log = &chip->log; struct tcg_pcr_event *event_header = log->bios_event_log; - struct tcg_pcr_event2 *event = v; + struct tcg_pcr_event2_hdr *event = v; void *temp_ptr; size_t size; diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index d9439f9abe78..33abe5406d38 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -488,21 +488,37 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) { int rc; - struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)]; u32 count = 0; - int i; + int i, size = 0; + void *tmp, *digest_list = NULL; chip = tpm_find_get_ops(chip); if (!chip) return -ENODEV; if (chip->flags & TPM_CHIP_FLAG_TPM2) { - memset(digest_list, 0, sizeof(digest_list)); - - for (i = 0; i < ARRAY_SIZE(chip->active_banks) && - chip->active_banks[i] != TPM2_ALG_ERROR; i++) { - digest_list[i].alg_id = chip->active_banks[i]; - memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE); + for (i = 0; i < ARRAY_SIZE(chip->active_banks); i++) { + int digest_size; + struct tpm2_digest_hdr *digest; + + if (chip->active_banks[i] == TPM2_ALG_ERROR) + continue; + + digest_size = tpm2_digest_size(chip->active_banks[i]); + if (digest_size < 0) + continue; + + digest = (struct tpm2_digest_hdr *)(digest_list + size); + size += sizeof(struct tpm2_digest_hdr) + digest_size; + + tmp = krealloc(digest_list, size, GFP_KERNEL); + if (!tmp) { + kfree(digest_list); + return -ENOMEM; + } + digest_list = tmp; + digest->alg_id = chip->active_banks[i]; + memcpy(digest->digest, hash, digest_size); count++; } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index f27d1f38a93d..178c47763d0c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -560,7 +560,7 @@ static inline u32 tpm2_rc_value(u32 rc) int tpm2_get_timeouts(struct tpm_chip *chip); int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf); int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, - struct tpm2_digest *digests); + struct tpm2_digest_hdr *digests); int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max); void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, unsigned int flags); @@ -584,6 +584,7 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc, u8 *cmd); int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc, u8 *buf, size_t *bufsiz); +int tpm2_digest_size(int algo_id); int tpm_bios_log_setup(struct tpm_chip *chip); void tpm_bios_log_teardown(struct tpm_chip *chip); diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index a6bec13afa69..c91a0c1ef192 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -226,7 +226,7 @@ struct tpm2_null_auth_area { * Return: Same as with tpm_transmit_cmd. */ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, - struct tpm2_digest *digests) + struct tpm2_digest_hdr *digests) { struct tpm_buf buf; struct tpm2_null_auth_area auth_area; @@ -1027,3 +1027,16 @@ int tpm2_find_cc(struct tpm_chip *chip, u32 cc) return -1; } + +int tpm2_digest_size(int algo_id) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { + if (algo_id != tpm2_hash_map[i].tpm_id) + continue; + return hash_digest_size[tpm2_hash_map[i].crypto_id]; + } + + return -1; +} diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index b43bd2ea8bab..6363c8b08908 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -108,20 +108,35 @@ struct tcg_event_field { u8 event[0]; } __packed; -struct tpm2_digest { +struct tpm2_digest_hdr { u16 alg_id; - u8 digest[SHA512_DIGEST_SIZE]; + u8 digest[0]; } __packed; -struct tcg_pcr_event2 { +struct tcg_pcr_event2_hdr { u32 pcr_idx; u32 event_type; u32 count; - struct tpm2_digest digests[TPM2_ACTIVE_PCR_BANKS]; - struct tcg_event_field event; + struct tpm2_digest_hdr digests[0]; } __packed; -static inline int _calc_tpm2_event_size(struct tcg_pcr_event2 *event, +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[]; +}; + +static inline int _calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event, struct tcg_pcr_event *event_header) { struct tcg_efi_specid_event *efispecid; From patchwork Wed Jan 9 01:48:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10753353 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 1FDFE91E for ; Wed, 9 Jan 2019 01:49:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0E6BE28672 for ; Wed, 9 Jan 2019 01:49:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 00868287C0; Wed, 9 Jan 2019 01:49:02 +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 32EDD28672 for ; Wed, 9 Jan 2019 01:49:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729191AbfAIBtC (ORCPT ); Tue, 8 Jan 2019 20:49:02 -0500 Received: from mail-io1-f73.google.com ([209.85.166.73]:41299 "EHLO mail-io1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729102AbfAIBtB (ORCPT ); Tue, 8 Jan 2019 20:49:01 -0500 Received: by mail-io1-f73.google.com with SMTP id a12so4954790iok.8 for ; Tue, 08 Jan 2019 17:49:00 -0800 (PST) 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=s2+alvcRvFkRmPP4iRh2C5hWnObYLHtxbuHqeX3fJ28=; b=ryM8ikXy2eUdQlh7u4ByTLnoDpZq93Xb0xhdUr+uD0XQ+0zfVVXE1TMFqeUtA6jUEP V4VgLXdlwKYki0r0vSWZRVKNMTGTB637b/njRvUVitt6/XKskd3fyiNtP+rn+7GfjnCa ybA+cEmXaZLxgIoR98dVo1WdvTlWDVysSeLmx0KxHW0YwWYfP5G1zlu7ceNwq3QpCqC+ lD6tUE+2J2iI36BTCsj1FZfbfP54AKWk5oUarr8BNC/Cgq/a+7cA4wf/BZQqYBPF7xaW jwDC62j9tAAfaNjGMDG++xdnQMG14bzNd3FVwwWNHhFbQ6hMDFBnWHFm2imsTfWe9tVw k9CA== 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=s2+alvcRvFkRmPP4iRh2C5hWnObYLHtxbuHqeX3fJ28=; b=cXF0wK9sDBA2UzvAIxStfYYw6W1b3EJUbiO2YbOWBJy0gcL2Lru6gMbwnpG/137cY4 jbRYQwIXND5LMS7KcNLfrn921jsFuLTiffJpLwTb1wl+K+Bjz6SXf6G1WpRYBH+MMyDe 0OoluSq1wiHPsfp1wjuqy2ySTkgD2RKIZDCxC+9lGtkb0FQS4CnDM3Gha2XHdv/SR4EM SxtudPVKmrNFmrLQuh90Hm/daTICxk67v3vOvlK9dniNcNeYWDX6LLrLOUdawlWtlBEF DM1pilNAAw/K88Icykt+3ONluw7ZBHbVif1Jt2yMXQw+sxMH8PLrzmJhIQxWW13Ul3jN mI2g== X-Gm-Message-State: AJcUukejRCC7TRIlhBuILO1VGN9e3aj5kmPuYFTs+YmRTzLfuzRMro72 7ZoCorVKccYMw+jKYedTk0bDwntXUamkd153+NjRqYzDQ6H2tIlzLGjU1KtDDi3x45eQj2JTooL v/IiPOs/FevsRShlVKLYj0u6iJSr7G2KsWjYUyqO9jBiarKSwVipPiu01lH8YZat2QA6sZPt8fT EGUO6LnVN5490l0R++fag= X-Google-Smtp-Source: ALg8bN5Q4Mv+WI+z+wu15KSKZz+/Y6tnWXXLKLSd1Ih/d//d3qEt2BxdJPGflaUlvNdg8AMen6rbnZHQMCYyW3S3zSKOpw== X-Received: by 2002:a24:74e:: with SMTP id f75mr3191244itf.22.1546998540475; Tue, 08 Jan 2019 17:49:00 -0800 (PST) Date: Tue, 8 Jan 2019 17:48:45 -0800 In-Reply-To: <20190109014847.39980-1-matthewgarrett@google.com> Message-Id: <20190109014847.39980-4-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190109014847.39980-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.20.1.97.g81188d93c3-goog Subject: [PATCH 3/5] 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, 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. Signed-off-by: Matthew Garrett --- drivers/char/tpm/eventlog/tpm2.c | 2 +- drivers/firmware/efi/efi.c | 2 + drivers/firmware/efi/tpm.c | 67 ++++++++++++++++++++++---- include/linux/efi.h | 9 ++++ include/linux/tpm_eventlog.h | 82 +++++++++++++++++++++++++++++--- 5 files changed, 144 insertions(+), 18 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index 1343179c0a0e..45e379448a02 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c @@ -40,7 +40,7 @@ static int calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event, struct tcg_pcr_event *event_header) { - return _calc_tpm2_event_size(event, event_header); + return _calc_tpm2_event_size(event, event_header, NULL, NULL); } 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 4c46ff6f2242..bf4e9a254e23 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 0cbeb3d46b18..9d843af088b3 100644 --- a/drivers/firmware/efi/tpm.c +++ b/drivers/firmware/efi/tpm.c @@ -10,31 +10,78 @@ #include #include #include +#include #include +int efi_tpm_final_log_size; +EXPORT_SYMBOL(efi_tpm_final_log_size); + +int tpm2_event_log_length(void *data, int count, void *size_info) +{ + struct tcg_pcr_event2_hdr *header; + int event_size, size = 0; + + while (count > 0) { + header = data + size; + event_size = _calc_tpm2_event_size(header, size_info, + early_memremap, + early_memunmap); + if (event_size == 0) + return -1; + size += event_size; + } + 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; - if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) + if (efi.tpm_log != EFI_INVALID_TABLE_ADDR) { + 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_INVALID_TABLE_ADDR; + return -ENOMEM; + } + + tbl_size = sizeof(*log_tbl) + log_tbl->size; + memblock_reserve(efi.tpm_log, tbl_size); + early_memunmap(log_tbl, sizeof(*log_tbl)); + } else { + /* + * We can't calculate the size of the final events without the + * first entry in the TPM log, so bail here. + */ return 0; + } + + if (efi.tpm_final_log != EFI_INVALID_TABLE_ADDR) { + 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; + return -ENOMEM; + } - 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_INVALID_TABLE_ADDR; - return -ENOMEM; + tbl_size = tpm2_event_log_length(final_tbl->events, + final_tbl->number_of_events, + (void *)efi.tpm_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; } - tbl_size = sizeof(*log_tbl) + log_tbl->size; - memblock_reserve(efi.tpm_log, tbl_size); - early_memunmap(log_tbl, sizeof(*log_tbl)); return 0; } diff --git a/include/linux/efi.h b/include/linux/efi.h index 45ff763fba76..a6134c301fa7 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -676,6 +676,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 { @@ -983,6 +984,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; @@ -1700,6 +1702,13 @@ struct linux_efi_tpm_eventlog { extern int efi_tpm_eventlog_init(void); +struct efi_tcg2_final_events_table { + u64 version; + u64 number_of_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 6363c8b08908..612f177d09af 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -136,11 +136,21 @@ struct tcg_algorithm_info { struct tcg_algorithm_size digest_sizes[]; }; +/* + * This can be called in two contexts - when the event is already mapped, + * and when it isn't. In the latter case we don't know how much space we + * need to map in advance so need to jump through this repeated map/unmap + * dance as we learn more about the size of the event. + */ static inline int _calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event, - struct tcg_pcr_event *event_header) + struct tcg_pcr_event *event_header, + void *(*map)(resource_size_t, unsigned long), + void (*unmap)(void *, unsigned long)) { struct tcg_efi_specid_event *efispecid; struct tcg_event_field *event_field; + void *mapping = NULL; + int mapping_size; void *marker; void *marker_start; u32 halg_size; @@ -154,36 +164,94 @@ static inline int _calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event, marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type) + sizeof(event->count); + /* Map the event header */ + if (map) { + mapping_size = marker - marker_start; + mapping = map((unsigned long)marker_start, mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } + efispecid = (struct tcg_efi_specid_event *)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); + + /* Map the digest's algorithm identifier */ + if (map && unmap) { + unmap(mapping, mapping_size); + mapping_size = marker - marker_start + halg_size; + mapping = map((unsigned long)marker_start, + mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } + 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; + + /* Map the digest content itself */ + if (map && unmap) { + unmap(mapping, mapping_size); + mapping_size = marker - marker_start; + mapping = map((unsigned long)marker_start, + mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } break; } } /* Algorithm without known length. Such event is unparseable. */ - if (j == efispecid->num_algs) - return 0; + if (j == efispecid->num_algs) { + size = 0; + goto out; + } } event_field = (struct tcg_event_field *)marker; + + /* + * Map the event size - we don't read from the event itself, so + * we don't need to map it + */ + if (map && unmap) { + unmap(marker_start, mapping_size); + mapping_size += sizeof(event_field->event_size); + mapping = map((unsigned long)marker_start, mapping_size); + if (!mapping) { + size = 0; + goto out; + } + } + 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 (unmap) + unmap(mapping, mapping_size); return size; } + #endif From patchwork Wed Jan 9 01:48:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10753355 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 C76AA6C5 for ; Wed, 9 Jan 2019 01:49:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B71CA28672 for ; Wed, 9 Jan 2019 01:49:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AB796287C0; Wed, 9 Jan 2019 01:49:04 +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 5339C28672 for ; Wed, 9 Jan 2019 01:49:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729211AbfAIBtE (ORCPT ); Tue, 8 Jan 2019 20:49:04 -0500 Received: from mail-yw1-f73.google.com ([209.85.161.73]:52980 "EHLO mail-yw1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729102AbfAIBtE (ORCPT ); Tue, 8 Jan 2019 20:49:04 -0500 Received: by mail-yw1-f73.google.com with SMTP id v131so3119866ywb.19 for ; Tue, 08 Jan 2019 17:49:03 -0800 (PST) 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=a2/g6WvX/TfCcgWUWv30CCvvLsF3HVjVhKobZPS9laM=; b=AhnEYhGn0oQbQJID7WRlTTTXprjANm8bo9i6Py0XZv04H5ZBDBr7QW8EgAqxcxURw3 uU9r8f2DXSgNTG72JV2L0qAJPqRT6MXBFBGxWLEPmZKcbJVqzky5SqldFq/GgZikYTXE zUnlKM8KLIywWQZQQRfVRQl7DO7VWhtQX0hpcaRRQKlpebvtuFUEhfcPxPyuB7S9bPqv YSoBdefDQ9KrJ+iR9Qq+smpDFW3FFVa9T1s5YS8Bpq1Ygwaf58lFxGcxKUByhyFy1AyE lZePF022cJZ430LH2QFtqogNOcizxT/4W2y5YkEe0JGadplf9I9ETN7cjSv4MHIthB1P 2Awg== 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=a2/g6WvX/TfCcgWUWv30CCvvLsF3HVjVhKobZPS9laM=; b=Eq0CkOqb7lOTP7bH/k+o8jirlVQzKnPCJOykBzytYvPW9eTlMgZYaKPiiFuYObl6Sm Q5XNnM09Nxxz8hiCcG+YPS3JUwTbIFp+KZABSJ92QFmPl/ykDxontqI0A92kvy/Jf0ZT z1z/ekLULxdAc/D3i77sb80Kh4DggF0WW4mUJHQ0aZh9x3NCmJjoYAZm3NXl7MGf24Hl 6xr81dOX1Pg04hBljYwBXxU8rMOmRo/1RiclUAwbgR0ZdFM0Z3E/s3iIRI+vYkWpOZGV O6QK7pnrgc3pACU8We0/0KH5FkvTQlmisdf8+RunumgUrTRJ8bpLoWocc5LxotuGvXnC RJhA== X-Gm-Message-State: AJcUukfiC16vpCoi1cjsZls55rr4dXvx+ysw+Kb3Xrt9mwLS6SVl3ZBQ QmJdgssOVWCra3yJ/4oNNF41bM7Du7rgGS3ppHnpWnUkhRCwoVzxj0UQptkN6LTJrOYjejUkBhN JwZwxafj1qgAmilwrggevVWkQ+Zpuoh64n2xEQH0N2WgGEe92K02bwy9VRyile83uWN9M/2ca1O OMschzdn6DGa2z8z6LQYI= X-Google-Smtp-Source: ALg8bN45HWGCMnksZOzdN/vo4fTpb2i12uLDvxaFFPK/Xph571Cs6roj8t9fCfpiNOAvw7SVVG3BNv3+tSHJQ2IB3FF3VQ== X-Received: by 2002:a5b:c:: with SMTP id a12mr1914054ybp.18.1546998542803; Tue, 08 Jan 2019 17:49:02 -0800 (PST) Date: Tue, 8 Jan 2019 17:48:46 -0800 In-Reply-To: <20190109014847.39980-1-matthewgarrett@google.com> Message-Id: <20190109014847.39980-5-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190109014847.39980-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.20.1.97.g81188d93c3-goog Subject: [PATCH 4/5] 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, 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 | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/eventlog/efi.c b/drivers/char/tpm/eventlog/efi.c index 3e673ab22cb4..80e9ec28a9be 100644 --- a/drivers/char/tpm/eventlog/efi.c +++ b/drivers/char/tpm/eventlog/efi.c @@ -21,10 +21,12 @@ 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; if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) return -ENODEV; @@ -55,12 +57,41 @@ int tpm_read_log_efi(struct tpm_chip *chip) if (!log->bios_event_log) goto err_memunmap; log->bios_event_log_end = log->bios_event_log + log_size; - tpm_log_version = log_tbl->version; + + if (efi.tpm_final_log != EFI_INVALID_TABLE_ADDR && + efi_tpm_final_log_size != 0) { + if (tpm_log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { + 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); + goto err_memunmap; + } + + tmp = krealloc(log->bios_event_log, + log_size + efi_tpm_final_log_size, + GFP_KERNEL); + if (!tmp) { + kfree(log->bios_event_log); + goto err_memunmap; + } + + 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; + } + } + memunmap(final_tbl); memunmap(log_tbl); return tpm_log_version; err_memunmap: + memunmap(final_tbl); memunmap(log_tbl); return -ENOMEM; } From patchwork Wed Jan 9 01:48:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Garrett X-Patchwork-Id: 10753357 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 2E2A56C5 for ; Wed, 9 Jan 2019 01:49:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1CCC228672 for ; Wed, 9 Jan 2019 01:49:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 11294287C0; Wed, 9 Jan 2019 01:49:08 +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 F3EFA28672 for ; Wed, 9 Jan 2019 01:49:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729201AbfAIBtG (ORCPT ); Tue, 8 Jan 2019 20:49:06 -0500 Received: from mail-qk1-f201.google.com ([209.85.222.201]:39550 "EHLO mail-qk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729102AbfAIBtG (ORCPT ); Tue, 8 Jan 2019 20:49:06 -0500 Received: by mail-qk1-f201.google.com with SMTP id d196so4862025qkb.6 for ; Tue, 08 Jan 2019 17:49:05 -0800 (PST) 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=fmceAa53ADyVwcjwEGe3ntrNImDgoRPn1GmIc7NTZv8=; b=NzI2516VT9pxylOPL0lN9XHDmFy8HP5szx3mWFhU/uwVA1MQTsidlmsKFJGy7XMDX9 G6GbTiIe2o9DmUIWr1xT6KJyU4TyokCGFEKeNAWcHMl03QvnhoFn6Am05xOmX7Xr7uYb d+jZX3046aHbuxWBTUYRvwrLXrbAaOcBJy2f85ilNyQy4X0Niv0lwx3FPBeFywXdbtSO bQqJMPBjsVcKDybe5z+GiNkPHkYXPDYq3gjR/gMc9dOyaQUMJEJDE12kLKkuWWxO0C0t s13BLyqN1dYGfvWrgHiE1wW6wjo4KLLV/agdFYb21oGVmz5QIR9vlig/AnDLBqt/Yuqc vRmA== 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=fmceAa53ADyVwcjwEGe3ntrNImDgoRPn1GmIc7NTZv8=; b=IbSrroSg9m7rqKUJdTxIWdSf4Wx4+xfgPS5Tiuj+Se/5cOXi4Pu3GShdDXKmu6oI4D EFeaXkCG6lip0/RuZ4BlXZpKSf4KO5YQR/49koX5DoAVwrYratiaExYEtpLKGSX/SK1I dpEk3j5dXYWe5nDQQCtFXbHRyO+24wwEgq6HjUNZOotCmOjc0N0XYmWyHIsNmNAvVhPe fyVW5w/Zyp9CjnuDjQpkBcjT/7WMQUNCZu+fofP3kYyVBcbAr5gmKzLgMnTla6dZjzEl LD5WqVV6+U6fNziLghIiBjnnA3UFlqKeBEVtWM7K/kUwDhTqSTj8XvKBqCrsl4Wsmkfj XVqA== X-Gm-Message-State: AJcUukf7xVzyzzWqdp3G4fp3yflhB2j+zotGVqePhFAI9cCcVoua8EQN G2EHDisS3xyKLcejhoVbVomhcM9gO1jUS3og0jfSE35wLj7Gz/9GQStTm4QHKJ7sW/TAe8m49dp 7szkXUVX63/CP6H3OJw4tJktn8ZSbLAAwRF1HaeAfpQ1DZ+EAxMrge9Yuj1y5dRMVrUBf7mcO1O JFPNytz83y8gsnQaI9H9Y= X-Google-Smtp-Source: ALg8bN66qCcGAC3D2a0fxnCw9HaJXNajUR7r2nbuOwwX03o8vyWuXjzDHfQ0lKJtIh3EDRlGlrYGv9QDN5rPbV8gjo+gbw== X-Received: by 2002:ac8:2d46:: with SMTP id o6mr2859252qta.35.1546998545157; Tue, 08 Jan 2019 17:49:05 -0800 (PST) Date: Tue, 8 Jan 2019 17:48:47 -0800 In-Reply-To: <20190109014847.39980-1-matthewgarrett@google.com> Message-Id: <20190109014847.39980-6-matthewgarrett@google.com> Mime-Version: 1.0 References: <20190109014847.39980-1-matthewgarrett@google.com> X-Mailer: git-send-email 2.20.1.97.g81188d93c3-goog Subject: [PATCH 5/5] 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, 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 --- 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 a90b0b8fc69a..7d4a045aa2c4 100644 --- a/drivers/firmware/efi/libstub/tpm.c +++ b/drivers/firmware/efi/libstub/tpm.c @@ -59,7 +59,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; @@ -69,6 +69,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, @@ -76,14 +77,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; /* @@ -98,8 +105,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 *)log_location, + NULL, NULL); + } 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; } @@ -116,7 +138,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, @@ -128,9 +150,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); -}