From patchwork Wed Mar 29 07:43:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Vandrovec X-Patchwork-Id: 744653 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vtKs715S6z9ryj for ; Wed, 29 Mar 2017 18:58:51 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ct8VC-0001Rd-60; Wed, 29 Mar 2017 07:58:46 +0000 Received: from sog-mx-3.v43.ch3.sourceforge.com ([172.29.43.193] helo=mx.sourceforge.net) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ct8VB-0001RY-8L for tpmdd-devel@lists.sourceforge.net; Wed, 29 Mar 2017 07:58:45 +0000 Received-SPF: pass (sog-mx-3.v43.ch3.sourceforge.com: domain of vmware.com designates 208.91.0.190 as permitted sender) client-ip=208.91.0.190; envelope-from=petr@vmware.com; helo=EX13-EDG-OU-002.vmware.com; Received: from ex13-edg-ou-002.vmware.com ([208.91.0.190]) by sog-mx-3.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1ct8VA-0007oP-DD for tpmdd-devel@lists.sourceforge.net; Wed, 29 Mar 2017 07:58:45 +0000 Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-002.vmware.com (10.113.208.156) with Microsoft SMTP Server id 15.0.1156.6; Wed, 29 Mar 2017 00:42:41 -0700 Received: from petr-dev3.eng.vmware.com (petr-dev2.eng.vmware.com [10.20.93.186]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id 877EA40312; Wed, 29 Mar 2017 00:43:28 -0700 (PDT) Received: by petr-dev3.eng.vmware.com (Postfix, from userid 884) id 7E621A00211; Wed, 29 Mar 2017 00:43:28 -0700 (PDT) Date: Wed, 29 Mar 2017 00:43:28 -0700 From: Petr Vandrovec To: Peter Huewe Message-ID: <20170329074328.y5rmk5wh3rj5kgcg@petr-dev3.eng.vmware.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170306 (1.8.0) Received-SPF: None (EX13-EDG-OU-002.vmware.com: petr@vmware.com does not designate permitted sender hosts) X-Spam-Score: -1.5 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [208.91.0.190 listed in list.dnswl.org] -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-Headers-End: 1ct8VA-0007oP-DD Cc: tpmdd-devel@lists.sourceforge.net Subject: [tpmdd-devel] [PATCH 3/4] Autodetect TCG event log version X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: tpmdd-devel-bounces@lists.sourceforge.net From: Petr Vandrovec Code expects that TPM1 devices use TPM1 version of the log, and TPM2 devices use TPM2 version of the log. While that is strongly recommended by the spec, and now required by Microsoft certification, there are systems that use TPM2 chip with SHA-1 only log. So let's do detection based on first event in the log - if it is Spec ID Event03, log is crypto-agile log. otherwise it is SHA-1 log, or malformed bunch of bytes. I'm not entirely sure how this works on PPC64: tpm1_eventlog.c uses do_endian_conversion() on all accesses, while tpm2_eventlog.c never does conversion. I'm assuming that it is an ommission from tpm2_eventlog.c code. If PPC64 logs are really big-endian for TPM1 while native-endian for TPM2, let me know, and I'll modify detection code to handle both native and big endian formats. Signed-off-by: Petr Vandrovec --- drivers/char/tpm/tpm1_eventlog.c | 53 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm1_eventlog.c b/drivers/char/tpm/tpm1_eventlog.c index 9a8605e500b5..aafcecf19c48 100644 --- a/drivers/char/tpm/tpm1_eventlog.c +++ b/drivers/char/tpm/tpm1_eventlog.c @@ -375,6 +375,51 @@ static int tpm_read_log(struct tpm_chip *chip) } /* + * tpm_check_log_version - Check version of the event log. + * + * Returns 0 if it is TPM1 (SHA1-only) log, 1 if it is TPM2 + * log. -EIO if log appears to be malformed. + */ +static int tpm_check_log_version(const struct tpm_chip *chip) +{ + const struct tcpa_event *event = chip->log.bios_event_log; + size_t log_len = chip->log.bios_event_log_end - chip->log.bios_event_log; + u32 event_len; + const struct tcg_efi_specid_event *specid; + u32 num_algs; + + if (log_len < sizeof *event) + return -EIO; /* Too short for anything. */ + if (do_endian_conversion(event->pcr_index) != 0 || + do_endian_conversion(event->event_type) != NO_ACTION) + return 0; /* Not SpecID. Must be TPM1 log. */ + event_len = do_endian_conversion(event->event_size); + if (log_len - sizeof *event < event_len) + return -EIO; /* Too short for TPM1 or header event. */ + + /* + * Only Spec ID Event03 format is supported for TPM2. + * There was Spec ID Event02 format that did not include + * number of algorithms or digest sizes. To my knowledge + * there are no systems using that format. + */ + if (event_len < offsetof(struct tcg_efi_specid_event, digest_sizes)) + return 0; /* Too short for SpecID. Must be TPM1 log. */ + event_len -= offsetof(struct tcg_efi_specid_event, digest_sizes); + specid = (const struct tcg_efi_specid_event *)event->event_data; + if (memcmp(specid->signature, "Spec ID Event03", 16)) + return 0; /* Not Spec ID Event03, not TPM2. */ + + num_algs = do_endian_conversion(specid->num_algs); + /* Use division to avoid overflow if num_algs is huge number. */ + if (event_len / sizeof(struct tcg_efi_specid_event_algs) < num_algs) + return -EIO; /* Too short for digest sizes. */ + + /* Looks like TPM2 log. */ + return 1; +} + +/* * tpm_bios_log_setup() - Read the event log from the firmware * @chip: TPM chip to use. * @@ -394,6 +439,10 @@ int tpm_bios_log_setup(struct tpm_chip *chip) if (rc) return rc; + rc = tpm_check_log_version(chip); + if (rc < 0) + return rc; + cnt = 0; chip->bios_dir[cnt] = securityfs_create_dir(name, NULL); /* NOTE: securityfs_create_dir can return ENODEV if securityfs is @@ -404,7 +453,7 @@ int tpm_bios_log_setup(struct tpm_chip *chip) cnt++; chip->bin_log_seqops.chip = chip; - if (chip->flags & TPM_CHIP_FLAG_TPM2) + if (rc != 0) chip->bin_log_seqops.seqops = &tpm2_binary_b_measurements_seqops; else @@ -421,7 +470,7 @@ int tpm_bios_log_setup(struct tpm_chip *chip) goto err; cnt++; - if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { + if (rc == 0) { chip->ascii_log_seqops.chip = chip; chip->ascii_log_seqops.seqops =