From patchwork Tue Dec 4 08:21:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711265 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 C17151057 for ; Tue, 4 Dec 2018 08:25:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B965028CBC for ; Tue, 4 Dec 2018 08:25:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ADCDE2AC26; Tue, 4 Dec 2018 08:25: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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable 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 2654128CBC for ; Tue, 4 Dec 2018 08:25:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725983AbeLDIYz (ORCPT ); Tue, 4 Dec 2018 03:24:55 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32791 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726156AbeLDIYz (ORCPT ); Tue, 4 Dec 2018 03:24:55 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id C510C85FF6A11; Tue, 4 Dec 2018 08:24:51 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:24:47 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 1/7] tpm: dynamically allocate the allocated_banks array Date: Tue, 4 Dec 2018 09:21:32 +0100 Message-ID: <20181204082138.24600-2-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 This patch renames active_banks (member of tpm_chip) to allocated_banks, stores the number of allocated PCR banks in nr_allocated_banks (new member of tpm_chip), and replaces the static array with a pointer to a dynamically allocated array. tpm2_get_pcr_allocation() determines if a PCR bank is allocated by checking the mask in the TPML_PCR_SELECTION structure returned by the TPM for TPM2_Get_Capability(). One PCR bank with algorithm set to SHA1 is always allocated for TPM 1.x. As a consequence of the introduction of nr_allocated_banks, tpm_pcr_extend() does not check anymore if the algorithm stored in tpm_chip is equal to zero. Signed-off-by: Roberto Sassu Tested-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-chip.c | 1 + drivers/char/tpm/tpm-interface.c | 18 +++++++++-------- drivers/char/tpm/tpm.h | 3 ++- drivers/char/tpm/tpm1-cmd.c | 10 ++++++++++ drivers/char/tpm/tpm2-cmd.c | 34 ++++++++++++++++++++++---------- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 32db84683c40..ce851c62bb68 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -160,6 +160,7 @@ static void tpm_dev_release(struct device *dev) kfree(chip->log.bios_event_log); kfree(chip->work_space.context_buf); kfree(chip->work_space.session_buf); + kfree(chip->allocated_banks); kfree(chip); } diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index d9439f9abe78..7b80919228be 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -488,8 +488,7 @@ 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; + struct tpm2_digest *digest_list; int i; chip = tpm_find_get_ops(chip); @@ -497,16 +496,19 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) return -ENODEV; if (chip->flags & TPM_CHIP_FLAG_TPM2) { - memset(digest_list, 0, sizeof(digest_list)); + digest_list = kcalloc(chip->nr_allocated_banks, + sizeof(*digest_list), GFP_KERNEL); + if (!digest_list) + return -ENOMEM; - 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]; + for (i = 0; i < chip->nr_allocated_banks; i++) { + digest_list[i].alg_id = chip->allocated_banks[i]; memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE); - count++; } - rc = tpm2_pcr_extend(chip, pcr_idx, count, digest_list); + rc = tpm2_pcr_extend(chip, pcr_idx, chip->nr_allocated_banks, + digest_list); + kfree(digest_list); tpm_put_ops(chip); return rc; } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index f27d1f38a93d..6b94306ab7c5 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -257,7 +257,8 @@ struct tpm_chip { const struct attribute_group *groups[3]; unsigned int groups_cnt; - u16 active_banks[7]; + u32 nr_allocated_banks; + u16 *allocated_banks; #ifdef CONFIG_ACPI acpi_handle acpi_dev_handle; char ppi_version[TPM_PPI_VERSION_LEN + 1]; diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index 6f306338953b..0874743ca96d 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -709,6 +709,16 @@ int tpm1_auto_startup(struct tpm_chip *chip) goto out; } + chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks), + GFP_KERNEL); + if (!chip->allocated_banks) { + rc = -ENOMEM; + goto out; + } + + chip->allocated_banks[0] = TPM2_ALG_SHA1; + chip->nr_allocated_banks = 1; + return rc; out: if (rc > 0) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index a6bec13afa69..245669a7aba5 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -234,7 +234,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, int i; int j; - if (count > ARRAY_SIZE(chip->active_banks)) + if (count > chip->nr_allocated_banks) return -EINVAL; rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND); @@ -825,11 +825,14 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) void *marker; void *end; void *pcr_select_offset; - unsigned int count; u32 sizeof_pcr_selection; + u32 nr_possible_banks; + u32 nr_alloc_banks = 0; + u16 hash_alg; u32 rsp_len; int rc; int i = 0; + int j; rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY); if (rc) @@ -844,11 +847,14 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) if (rc) goto out; - count = be32_to_cpup( + nr_possible_banks = be32_to_cpup( (__be32 *)&buf.data[TPM_HEADER_SIZE + 5]); - if (count > ARRAY_SIZE(chip->active_banks)) { - rc = -ENODEV; + chip->allocated_banks = kcalloc(nr_possible_banks, + sizeof(*chip->allocated_banks), + GFP_KERNEL); + if (!chip->allocated_banks) { + rc = -ENOMEM; goto out; } @@ -857,7 +863,7 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) rsp_len = be32_to_cpup((__be32 *)&buf.data[2]); end = &buf.data[rsp_len]; - for (i = 0; i < count; i++) { + for (i = 0; i < nr_possible_banks; i++) { pcr_select_offset = marker + offsetof(struct tpm2_pcr_selection, size_of_select); if (pcr_select_offset >= end) { @@ -866,17 +872,25 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) } memcpy(&pcr_selection, marker, sizeof(pcr_selection)); - chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg); + hash_alg = be16_to_cpu(pcr_selection.hash_alg); + + for (j = 0; j < pcr_selection.size_of_select; j++) + if (pcr_selection.pcr_select[j]) + break; + + if (j < pcr_selection.size_of_select) { + chip->allocated_banks[nr_alloc_banks] = hash_alg; + nr_alloc_banks++; + } + sizeof_pcr_selection = sizeof(pcr_selection.hash_alg) + sizeof(pcr_selection.size_of_select) + pcr_selection.size_of_select; marker = marker + sizeof_pcr_selection; } + chip->nr_allocated_banks = nr_alloc_banks; out: - if (i < ARRAY_SIZE(chip->active_banks)) - chip->active_banks[i] = TPM2_ALG_ERROR; - tpm_buf_destroy(&buf); return rc; From patchwork Tue Dec 4 08:21:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711267 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 B167216B1 for ; Tue, 4 Dec 2018 08:25:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7E1028BE0 for ; Tue, 4 Dec 2018 08:25:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9C0EB2AC25; Tue, 4 Dec 2018 08:25:31 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI 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 0DE4A28CBC for ; Tue, 4 Dec 2018 08:25:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726005AbeLDIZa (ORCPT ); Tue, 4 Dec 2018 03:25:30 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32792 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725994AbeLDIZa (ORCPT ); Tue, 4 Dec 2018 03:25:30 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id 45A077BE33982; Tue, 4 Dec 2018 08:25:27 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:25:22 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 2/7] tpm: add _head suffix to tcg_efi_specid_event and tcg_pcr_event2 Date: Tue, 4 Dec 2018 09:21:33 +0100 Message-ID: <20181204082138.24600-3-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 TCG defines two structures, TCG_EfiSpecIDEventStruct and TCG_PCR_EVENT2, which contain variable-sized arrays in the middle of the definition. Since these structures are not suitable for type casting, this patch removes structure members after the variable-sized arrays and adds the _head suffix to the structure name, to indicate that the renamed structures do not contain all fields defined by TCG. Lastly, given that variable-sized arrays are now in the last position, and given that the size of the arrays cannot be determined in advance, this patch also sets the size of those arrays to zero and removes the definition of TPM2_ACTIVE_PCR_BANKS. Signed-off-by: Roberto Sassu Reviewed-by: Jarkko Sakkinen Tested-by: Nayna Jain --- drivers/char/tpm/eventlog/tpm2.c | 12 ++++++------ include/linux/tpm_eventlog.h | 12 ++++-------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c index 1b8fa9de2cac..d8b77133a83a 100644 --- a/drivers/char/tpm/eventlog/tpm2.c +++ b/drivers/char/tpm/eventlog/tpm2.c @@ -37,10 +37,10 @@ * * 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_head *event, struct tcg_pcr_event *event_header) { - struct tcg_efi_specid_event *efispecid; + struct tcg_efi_specid_event_head *efispecid; struct tcg_event_field *event_field; void *marker; void *marker_start; @@ -55,7 +55,7 @@ static int calc_tpm2_event_size(struct tcg_pcr_event2 *event, marker = marker + sizeof(event->pcr_idx) + sizeof(event->event_type) + sizeof(event->count); - efispecid = (struct tcg_efi_specid_event *)event_header->event; + efispecid = (struct tcg_efi_specid_event_head *)event_header->event; /* Check if event is malformed. */ if (event->count > efispecid->num_algs) @@ -95,7 +95,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_head *event; size_t size; int i; @@ -136,7 +136,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_head *event; struct tpm_chip *chip = m->private; struct tpm_bios_log *log = &chip->log; void *limit = log->bios_event_log_end; @@ -180,7 +180,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_head *event = v; void *temp_ptr; size_t size; diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index 20d9da77fc11..f0ef6cc97f00 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -8,7 +8,6 @@ #define TCG_EVENT_NAME_LEN_MAX 255 #define MAX_TEXT_EVENT 1000 /* Max event string length */ #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ -#define TPM2_ACTIVE_PCR_BANKS 3 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x1 #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x2 @@ -82,7 +81,7 @@ struct tcg_efi_specid_event_algs { u16 digest_size; } __packed; -struct tcg_efi_specid_event { +struct tcg_efi_specid_event_head { u8 signature[16]; u32 platform_class; u8 spec_version_minor; @@ -90,9 +89,7 @@ struct tcg_efi_specid_event { u8 spec_errata; u8 uintnsize; u32 num_algs; - struct tcg_efi_specid_event_algs digest_sizes[TPM2_ACTIVE_PCR_BANKS]; - u8 vendor_info_size; - u8 vendor_info[0]; + struct tcg_efi_specid_event_algs digest_sizes[0]; } __packed; struct tcg_pcr_event { @@ -113,12 +110,11 @@ struct tpm2_digest { u8 digest[SHA512_DIGEST_SIZE]; } __packed; -struct tcg_pcr_event2 { +struct tcg_pcr_event2_head { u32 pcr_idx; u32 event_type; u32 count; - struct tpm2_digest digests[TPM2_ACTIVE_PCR_BANKS]; - struct tcg_event_field event; + struct tpm2_digest digests[0]; } __packed; #endif From patchwork Tue Dec 4 08:21:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711271 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 56E211057 for ; Tue, 4 Dec 2018 08:26:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 49E2E2ABFA for ; Tue, 4 Dec 2018 08:26:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3E5DA2AC48; Tue, 4 Dec 2018 08:26: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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI 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 A29D22ABFA for ; Tue, 4 Dec 2018 08:26:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725994AbeLDI0B (ORCPT ); Tue, 4 Dec 2018 03:26:01 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32793 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725983AbeLDI0B (ORCPT ); Tue, 4 Dec 2018 03:26:01 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id B97138E250E94; Tue, 4 Dec 2018 08:25:57 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:25:52 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 3/7] tpm: rename and export tpm2_digest and tpm2_algorithms Date: Tue, 4 Dec 2018 09:21:34 +0100 Message-ID: <20181204082138.24600-4-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 Rename tpm2_* to tpm_* and move the definitions to include/linux/tpm.h so that these can be used by other kernel subsystems (e.g. IMA). Signed-off-by: Roberto Sassu Reviewed-by: Jarkko Sakkinen Acked-by: Mimi Zohar --- drivers/char/tpm/tpm-interface.c | 2 +- drivers/char/tpm/tpm.h | 13 +------------ drivers/char/tpm/tpm1-cmd.c | 2 +- drivers/char/tpm/tpm2-cmd.c | 18 +++++++++--------- include/linux/tpm.h | 18 ++++++++++++++++++ include/linux/tpm_eventlog.h | 9 ++------- 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 7b80919228be..96c8261d0f04 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -488,7 +488,7 @@ 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; + struct tpm_digest *digest_list; int i; chip = tpm_find_get_ops(chip); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 6b94306ab7c5..e961e5c5d197 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -122,17 +122,6 @@ enum tpm2_return_codes { TPM2_RC_RETRY = 0x0922, }; -enum tpm2_algorithms { - TPM2_ALG_ERROR = 0x0000, - TPM2_ALG_SHA1 = 0x0004, - TPM2_ALG_KEYEDHASH = 0x0008, - TPM2_ALG_SHA256 = 0x000B, - TPM2_ALG_SHA384 = 0x000C, - TPM2_ALG_SHA512 = 0x000D, - TPM2_ALG_NULL = 0x0010, - TPM2_ALG_SM3_256 = 0x0012, -}; - enum tpm2_command_codes { TPM2_CC_FIRST = 0x011F, TPM2_CC_HIERARCHY_CONTROL = 0x0121, @@ -561,7 +550,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 tpm_digest *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); diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index 0874743ca96d..ec4f197bae0a 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -716,7 +716,7 @@ int tpm1_auto_startup(struct tpm_chip *chip) goto out; } - chip->allocated_banks[0] = TPM2_ALG_SHA1; + chip->allocated_banks[0] = TPM_ALG_SHA1; chip->nr_allocated_banks = 1; return rc; diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 245669a7aba5..4afd14892cbf 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -33,11 +33,11 @@ struct tpm2_hash { }; static struct tpm2_hash tpm2_hash_map[] = { - {HASH_ALGO_SHA1, TPM2_ALG_SHA1}, - {HASH_ALGO_SHA256, TPM2_ALG_SHA256}, - {HASH_ALGO_SHA384, TPM2_ALG_SHA384}, - {HASH_ALGO_SHA512, TPM2_ALG_SHA512}, - {HASH_ALGO_SM3_256, TPM2_ALG_SM3_256}, + {HASH_ALGO_SHA1, TPM_ALG_SHA1}, + {HASH_ALGO_SHA256, TPM_ALG_SHA256}, + {HASH_ALGO_SHA384, TPM_ALG_SHA384}, + {HASH_ALGO_SHA512, TPM_ALG_SHA512}, + {HASH_ALGO_SM3_256, TPM_ALG_SM3_256}, }; int tpm2_get_timeouts(struct tpm_chip *chip) @@ -192,7 +192,7 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7); tpm_buf_append_u32(&buf, 1); - tpm_buf_append_u16(&buf, TPM2_ALG_SHA1); + tpm_buf_append_u16(&buf, TPM_ALG_SHA1); tpm_buf_append_u8(&buf, TPM2_PCR_SELECT_MIN); tpm_buf_append(&buf, (const unsigned char *)pcr_select, sizeof(pcr_select)); @@ -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 tpm_digest *digests) { struct tpm_buf buf; struct tpm2_null_auth_area auth_area; @@ -449,7 +449,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, /* public */ tpm_buf_append_u16(&buf, 14 + options->policydigest_len); - tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); + tpm_buf_append_u16(&buf, TPM_ALG_KEYEDHASH); tpm_buf_append_u16(&buf, hash); /* policy */ @@ -464,7 +464,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, } /* public parameters */ - tpm_buf_append_u16(&buf, TPM2_ALG_NULL); + tpm_buf_append_u16(&buf, TPM_ALG_NULL); tpm_buf_append_u16(&buf, 0); /* outside info */ diff --git a/include/linux/tpm.h b/include/linux/tpm.h index b49a55cf775f..330c0a481581 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -22,12 +22,30 @@ #ifndef __LINUX_TPM_H__ #define __LINUX_TPM_H__ +#include + #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ struct tpm_chip; struct trusted_key_payload; struct trusted_key_options; +enum tpm_algorithms { + TPM_ALG_ERROR = 0x0000, + TPM_ALG_SHA1 = 0x0004, + TPM_ALG_KEYEDHASH = 0x0008, + TPM_ALG_SHA256 = 0x000B, + TPM_ALG_SHA384 = 0x000C, + TPM_ALG_SHA512 = 0x000D, + TPM_ALG_NULL = 0x0010, + TPM_ALG_SM3_256 = 0x0012, +}; + +struct tpm_digest { + u16 alg_id; + u8 digest[SHA512_DIGEST_SIZE]; +} __packed; + enum TPM_OPS_FLAGS { TPM_OPS_AUTO_STARTUP = BIT(0), }; diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h index f0ef6cc97f00..1d2d10a27bbe 100644 --- a/include/linux/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h @@ -3,7 +3,7 @@ #ifndef __LINUX_TPM_EVENTLOG_H__ #define __LINUX_TPM_EVENTLOG_H__ -#include +#include #define TCG_EVENT_NAME_LEN_MAX 255 #define MAX_TEXT_EVENT 1000 /* Max event string length */ @@ -105,16 +105,11 @@ struct tcg_event_field { u8 event[0]; } __packed; -struct tpm2_digest { - u16 alg_id; - u8 digest[SHA512_DIGEST_SIZE]; -} __packed; - struct tcg_pcr_event2_head { u32 pcr_idx; u32 event_type; u32 count; - struct tpm2_digest digests[0]; + struct tpm_digest digests[0]; } __packed; #endif From patchwork Tue Dec 4 08:21:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711277 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 A46851057 for ; Tue, 4 Dec 2018 08:26:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99A2E28BE0 for ; Tue, 4 Dec 2018 08:26:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8AA2828CBF; Tue, 4 Dec 2018 08:26:43 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable 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 EE04328BE0 for ; Tue, 4 Dec 2018 08:26:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726126AbeLDI0h (ORCPT ); Tue, 4 Dec 2018 03:26:37 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32794 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725983AbeLDI0g (ORCPT ); Tue, 4 Dec 2018 03:26:36 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id 3C49041DC124E; Tue, 4 Dec 2018 08:26:33 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:26:27 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 4/7] tpm: modify tpm_pcr_read() definition to pass a TPM hash algorithm Date: Tue, 4 Dec 2018 09:21:35 +0100 Message-ID: <20181204082138.24600-5-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 Currently the TPM driver allows other kernel subsystems to read only the SHA1 PCR bank. This patch modifies the parameters of tpm_pcr_read() and tpm2_pcr_read() to pass a tpm_digest structure, which contains the desired hash algorithm. Also, since commit 125a22105410 ("tpm: React correctly to RC_TESTING from TPM 2.0 self tests") removed the call to tpm2_pcr_read(), the new parameter is expected to be always not NULL. Due to the API change, IMA functions have been modified. Signed-off-by: Roberto Sassu Acked-by: Mimi Zohar Reviewed-by: Jarkko Sakkinen Tested-by: Nayna Jain --- drivers/char/tpm/tpm-interface.c | 9 +++++---- drivers/char/tpm/tpm.h | 3 ++- drivers/char/tpm/tpm2-cmd.c | 23 ++++++++++++++++------- include/linux/tpm.h | 6 ++++-- security/integrity/ima/ima_crypto.c | 10 +++++----- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 96c8261d0f04..cea4c8d75ad0 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -451,11 +451,12 @@ EXPORT_SYMBOL_GPL(tpm_is_tpm2); * tpm_pcr_read - read a PCR value from SHA1 bank * @chip: a &struct tpm_chip instance, %NULL for the default chip * @pcr_idx: the PCR to be retrieved - * @res_buf: the value of the PCR + * @digest: the PCR bank and buffer current PCR value is written to * * Return: same as with tpm_transmit_cmd() */ -int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) +int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, + struct tpm_digest *digest) { int rc; @@ -464,9 +465,9 @@ int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) return -ENODEV; if (chip->flags & TPM_CHIP_FLAG_TPM2) - rc = tpm2_pcr_read(chip, pcr_idx, res_buf); + rc = tpm2_pcr_read(chip, pcr_idx, digest); else - rc = tpm1_pcr_read(chip, pcr_idx, res_buf); + rc = tpm1_pcr_read(chip, pcr_idx, digest->digest); tpm_put_ops(chip); return rc; diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index e961e5c5d197..343aa58424f7 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -548,7 +548,8 @@ 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_read(struct tpm_chip *chip, u32 pcr_idx, + struct tpm_digest *digest); int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, struct tpm_digest *digests); int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max); diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 4afd14892cbf..81740d55f19c 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -171,16 +171,18 @@ struct tpm2_pcr_read_out { * tpm2_pcr_read() - read a PCR value * @chip: TPM chip to use. * @pcr_idx: index of the PCR to read. - * @res_buf: buffer to store the resulting hash. + * @digest: PCR bank and buffer current PCR value is written to. * * Return: Same as with tpm_transmit_cmd. */ -int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) +int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, + struct tpm_digest *digest) { int rc; struct tpm_buf buf; struct tpm2_pcr_read_out *out; u8 pcr_select[TPM2_PCR_SELECT_MIN] = {0}; + u16 digest_size; if (pcr_idx >= TPM2_PLATFORM_PCR) return -EINVAL; @@ -192,18 +194,25 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7); tpm_buf_append_u32(&buf, 1); - tpm_buf_append_u16(&buf, TPM_ALG_SHA1); + tpm_buf_append_u16(&buf, digest->alg_id); tpm_buf_append_u8(&buf, TPM2_PCR_SELECT_MIN); tpm_buf_append(&buf, (const unsigned char *)pcr_select, sizeof(pcr_select)); rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, - res_buf ? "attempting to read a pcr value" : NULL); - if (rc == 0 && res_buf) { - out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; - memcpy(res_buf, out->digest, SHA1_DIGEST_SIZE); + "attempting to read a pcr value"); + if (rc) + goto out; + + out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; + digest_size = be16_to_cpu(out->digest_size); + if (digest_size > sizeof(digest->digest)) { + rc = -EINVAL; + goto out; } + memcpy(digest->digest, out->digest, digest_size); +out: tpm_buf_destroy(&buf); return rc; } diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 330c0a481581..95e11688826e 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -71,7 +71,8 @@ struct tpm_class_ops { #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) extern int tpm_is_tpm2(struct tpm_chip *chip); -extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf); +extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, + struct tpm_digest *digest); extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash); extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen); extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max); @@ -88,7 +89,8 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip) return -ENODEV; } -static inline int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf) +static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, + struct tpm_digest *digest) { return -ENODEV; } diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index acf2c7df7145..16a4f45863b1 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -643,12 +643,12 @@ int ima_calc_buffer_hash(const void *buf, loff_t len, return calc_buffer_shash(buf, len, hash); } -static void __init ima_pcrread(u32 idx, u8 *pcr) +static void __init ima_pcrread(u32 idx, struct tpm_digest *d) { if (!ima_tpm_chip) return; - if (tpm_pcr_read(ima_tpm_chip, idx, pcr) != 0) + if (tpm_pcr_read(ima_tpm_chip, idx, d) != 0) pr_err("Error Communicating to TPM chip\n"); } @@ -658,7 +658,7 @@ static void __init ima_pcrread(u32 idx, u8 *pcr) static int __init ima_calc_boot_aggregate_tfm(char *digest, struct crypto_shash *tfm) { - u8 pcr_i[TPM_DIGEST_SIZE]; + struct tpm_digest d = { .alg_id = TPM_ALG_SHA1, .digest = {0} }; int rc; u32 i; SHASH_DESC_ON_STACK(shash, tfm); @@ -672,9 +672,9 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest, /* cumulative sha1 over tpm registers 0-7 */ for (i = TPM_PCR0; i < TPM_PCR8; i++) { - ima_pcrread(i, pcr_i); + ima_pcrread(i, &d); /* now accumulate with current aggregate */ - rc = crypto_shash_update(shash, pcr_i, TPM_DIGEST_SIZE); + rc = crypto_shash_update(shash, d.digest, TPM_DIGEST_SIZE); } if (!rc) crypto_shash_final(shash, digest); From patchwork Tue Dec 4 08:21:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711281 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 BBBF516B1 for ; Tue, 4 Dec 2018 08:27:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AEB6628CBC for ; Tue, 4 Dec 2018 08:27:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B34D2ABFA; Tue, 4 Dec 2018 08:27: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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable 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 0175B28CBC for ; Tue, 4 Dec 2018 08:27:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726020AbeLDI1H (ORCPT ); Tue, 4 Dec 2018 03:27:07 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32795 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725983AbeLDI1H (ORCPT ); Tue, 4 Dec 2018 03:27:07 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id A2E18FBCCA0A8; Tue, 4 Dec 2018 08:27:03 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:26:57 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 5/7] tpm: retrieve digest size of unknown algorithms with PCR read Date: Tue, 4 Dec 2018 09:21:36 +0100 Message-ID: <20181204082138.24600-6-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 Currently, the TPM driver retrieves the digest size from a table mapping TPM algorithms identifiers to identifiers defined by the crypto subsystem. If the algorithm is not defined by the latter, the digest size can be retrieved from the output of the PCR read command. The patch retrieves at TPM startup the digest sizes for each PCR bank and stores them in the new structure tpm_bank_info, member of tpm_chip, so that the information can be passed to other kernel subsystems. tpm_bank_info contains: the TPM algorithm identifier, necessary to generate the event log as defined by Trusted Computing Group (TCG); the digest size, to pad/truncate a digest calculated with a different algorithm; the crypto subsystem identifier, to calculate the digest of event data. Signed-off-by: Roberto Sassu Reviewed-by: Jarkko Sakkinen Acked-by: Mimi Zohar --- drivers/char/tpm/tpm-interface.c | 9 +++---- drivers/char/tpm/tpm.h | 4 +-- drivers/char/tpm/tpm1-cmd.c | 4 ++- drivers/char/tpm/tpm2-cmd.c | 45 ++++++++++++++++++++++++-------- include/linux/tpm.h | 6 +++++ 5 files changed, 49 insertions(+), 19 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index cea4c8d75ad0..eb7c79ca8a94 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -465,7 +465,7 @@ int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, return -ENODEV; if (chip->flags & TPM_CHIP_FLAG_TPM2) - rc = tpm2_pcr_read(chip, pcr_idx, digest); + rc = tpm2_pcr_read(chip, pcr_idx, digest, NULL); else rc = tpm1_pcr_read(chip, pcr_idx, digest->digest); @@ -480,9 +480,8 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); * @pcr_idx: the PCR to be retrieved * @hash: the hash value used to extend the PCR value * - * Note: with TPM 2.0 extends also those banks with a known digest size to the - * cryto subsystem in order to prevent malicious use of those PCR banks. In the - * future we should dynamically determine digest sizes. + * Note: with TPM 2.0 extends also those banks for which no digest was + * specified in order to prevent malicious use of those PCR banks. * * Return: same as with tpm_transmit_cmd() */ @@ -503,7 +502,7 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) return -ENOMEM; for (i = 0; i < chip->nr_allocated_banks; i++) { - digest_list[i].alg_id = chip->allocated_banks[i]; + digest_list[i].alg_id = chip->allocated_banks[i].alg_id; memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE); } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 343aa58424f7..64d93d26087f 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -247,7 +247,7 @@ struct tpm_chip { unsigned int groups_cnt; u32 nr_allocated_banks; - u16 *allocated_banks; + struct tpm_bank_info *allocated_banks; #ifdef CONFIG_ACPI acpi_handle acpi_dev_handle; char ppi_version[TPM_PPI_VERSION_LEN + 1]; @@ -549,7 +549,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, - struct tpm_digest *digest); + struct tpm_digest *digest, u16 *digest_size_ptr); int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, struct tpm_digest *digests); int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max); diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index ec4f197bae0a..8b70a7f884a7 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -716,7 +716,9 @@ int tpm1_auto_startup(struct tpm_chip *chip) goto out; } - chip->allocated_banks[0] = TPM_ALG_SHA1; + chip->allocated_banks[0].alg_id = TPM_ALG_SHA1; + chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1]; + chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1; chip->nr_allocated_banks = 1; return rc; diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 81740d55f19c..a804f0b7126a 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -172,11 +172,12 @@ struct tpm2_pcr_read_out { * @chip: TPM chip to use. * @pcr_idx: index of the PCR to read. * @digest: PCR bank and buffer current PCR value is written to. + * @digest_size_ptr: pointer to variable that stores the digest size. * * Return: Same as with tpm_transmit_cmd. */ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, - struct tpm_digest *digest) + struct tpm_digest *digest, u16 *digest_size_ptr) { int rc; struct tpm_buf buf; @@ -211,6 +212,9 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, goto out; } + if (digest_size_ptr) + *digest_size_ptr = digest_size; + memcpy(digest->digest, out->digest, digest_size); out: tpm_buf_destroy(&buf); @@ -241,7 +245,6 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, struct tpm2_null_auth_area auth_area; int rc; int i; - int j; if (count > chip->nr_allocated_banks) return -EINVAL; @@ -263,14 +266,9 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, tpm_buf_append_u32(&buf, count); for (i = 0; i < count; i++) { - for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) { - if (digests[i].alg_id != tpm2_hash_map[j].tpm_id) - continue; - tpm_buf_append_u16(&buf, digests[i].alg_id); - tpm_buf_append(&buf, (const unsigned char - *)&digests[i].digest, - hash_digest_size[tpm2_hash_map[j].crypto_id]); - } + tpm_buf_append_u16(&buf, digests[i].alg_id); + tpm_buf_append(&buf, (const unsigned char *)&digests[i].digest, + chip->allocated_banks[i].digest_size); } rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, @@ -821,6 +819,26 @@ int tpm2_probe(struct tpm_chip *chip) } EXPORT_SYMBOL_GPL(tpm2_probe); +static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index) +{ + struct tpm_bank_info *bank = chip->allocated_banks + bank_index; + struct tpm_digest digest = { .alg_id = bank->alg_id }; + int i; + + for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) { + enum hash_algo crypto_algo = tpm2_hash_map[i].crypto_id; + + if (bank->alg_id != tpm2_hash_map[i].tpm_id) + continue; + + bank->digest_size = hash_digest_size[crypto_algo]; + bank->crypto_id = crypto_algo; + return 0; + } + + return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size); +} + struct tpm2_pcr_selection { __be16 hash_alg; u8 size_of_select; @@ -888,7 +906,12 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) break; if (j < pcr_selection.size_of_select) { - chip->allocated_banks[nr_alloc_banks] = hash_alg; + chip->allocated_banks[nr_alloc_banks].alg_id = hash_alg; + + rc = tpm2_init_bank_info(chip, nr_alloc_banks); + if (rc < 0) + break; + nr_alloc_banks++; } diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 95e11688826e..72df8d4252ef 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -46,6 +46,12 @@ struct tpm_digest { u8 digest[SHA512_DIGEST_SIZE]; } __packed; +struct tpm_bank_info { + u16 alg_id; + u16 digest_size; + u16 crypto_id; +}; + enum TPM_OPS_FLAGS { TPM_OPS_AUTO_STARTUP = BIT(0), }; From patchwork Tue Dec 4 08:21:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711283 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 A14331057 for ; Tue, 4 Dec 2018 08:27:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 94ED528CBF for ; Tue, 4 Dec 2018 08:27:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85A322ABFA; Tue, 4 Dec 2018 08:27:43 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI 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 2BD0928B04 for ; Tue, 4 Dec 2018 08:27:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726047AbeLDI1i (ORCPT ); Tue, 4 Dec 2018 03:27:38 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32796 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726005AbeLDI1h (ORCPT ); Tue, 4 Dec 2018 03:27:37 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id 14BAFAD65D6BF; Tue, 4 Dec 2018 08:27:34 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:27:27 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 6/7] tpm: ensure that the output of PCR read contains the correct digest size Date: Tue, 4 Dec 2018 09:21:37 +0100 Message-ID: <20181204082138.24600-7-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 This patch protects against data corruption that could happen in the bus, by checking that the digest size returned by the TPM during a PCR read matches the size of the algorithm passed to tpm2_pcr_read(). This check is performed after information about the PCR banks has been retrieved. Signed-off-by: Roberto Sassu Reviewed-by: Jarkko Sakkinen --- drivers/char/tpm/tpm2-cmd.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index a804f0b7126a..d6d29480348c 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -179,15 +179,28 @@ struct tpm2_pcr_read_out { int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digest, u16 *digest_size_ptr) { + int i; int rc; struct tpm_buf buf; struct tpm2_pcr_read_out *out; u8 pcr_select[TPM2_PCR_SELECT_MIN] = {0}; u16 digest_size; + u16 expected_digest_size = 0; if (pcr_idx >= TPM2_PLATFORM_PCR) return -EINVAL; + if (!digest_size_ptr) { + for (i = 0; i < chip->nr_allocated_banks && + chip->allocated_banks[i].alg_id != digest->alg_id; i++) + ; + + if (i == chip->nr_allocated_banks) + return -EINVAL; + + expected_digest_size = chip->allocated_banks[i].digest_size; + } + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_PCR_READ); if (rc) return rc; @@ -207,7 +220,8 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; digest_size = be16_to_cpu(out->digest_size); - if (digest_size > sizeof(digest->digest)) { + if (digest_size > sizeof(digest->digest) || + (!digest_size_ptr && digest_size != expected_digest_size)) { rc = -EINVAL; goto out; } From patchwork Tue Dec 4 08:21:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 10711287 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 B9E251057 for ; Tue, 4 Dec 2018 08:28:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA8462ABFA for ; Tue, 4 Dec 2018 08:28:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9E0622AC17; Tue, 4 Dec 2018 08:28:22 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI 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 B9D0328B04 for ; Tue, 4 Dec 2018 08:28:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726142AbeLDI2Q (ORCPT ); Tue, 4 Dec 2018 03:28:16 -0500 Received: from lhrrgout.huawei.com ([185.176.76.210]:32797 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725983AbeLDI2N (ORCPT ); Tue, 4 Dec 2018 03:28:13 -0500 Received: from lhreml701-cah.china.huawei.com (unknown [172.18.7.108]) by Forcepoint Email with ESMTP id 96EABC2200E95; Tue, 4 Dec 2018 08:28:09 +0000 (GMT) Received: from roberto-HP-EliteDesk-800-G2-DM-65W.huawei.com (10.204.65.153) by smtpsuk.huawei.com (10.201.108.42) with Microsoft SMTP Server (TLS) id 14.3.408.0; Tue, 4 Dec 2018 08:28:02 +0000 From: Roberto Sassu To: , , , CC: , , , , Roberto Sassu Subject: [PATCH v6 7/7] tpm: pass an array of tpm_bank_list structures to tpm_pcr_extend() Date: Tue, 4 Dec 2018 09:21:38 +0100 Message-ID: <20181204082138.24600-8-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181204082138.24600-1-roberto.sassu@huawei.com> References: <20181204082138.24600-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.65.153] X-CFilter-Loop: Reflected 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 Currently, tpm_pcr_extend() accepts as an input only a SHA1 digest. This patch modifies the definition of tpm_pcr_extend() to allow other kernel subsystems to pass a digest for each algorithm supported by the TPM. All digests are processed by the TPM in one operation. If a tpm_pcr_extend() caller provides a subset of the supported algorithms, the TPM driver extends the remaining PCR banks with the first digest passed as an argument to the function. The new tpm_bank_list structure has been preferred to the tpm_digest structure, to let the caller specify the size of the digest (which may be unknown to the TPM driver). Due to the API change, ima_pcr_extend() and pcrlock() have been modified. Signed-off-by: Roberto Sassu --- drivers/char/tpm/tpm-interface.c | 24 +++++--------------- drivers/char/tpm/tpm.h | 6 ++--- drivers/char/tpm/tpm1-cmd.c | 14 ++++++++---- drivers/char/tpm/tpm2-cmd.c | 36 +++++++++++++++++++++--------- include/linux/tpm.h | 13 ++++++++--- security/integrity/ima/ima_queue.c | 5 ++++- security/keys/trusted.c | 5 ++++- 7 files changed, 63 insertions(+), 40 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index eb7c79ca8a94..36e00adaf509 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -478,42 +478,30 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read); * tpm_pcr_extend - extend a PCR value in SHA1 bank. * @chip: a &struct tpm_chip instance, %NULL for the default chip * @pcr_idx: the PCR to be retrieved - * @hash: the hash value used to extend the PCR value + * @count: number of tpm_bank_list structures + * @bank_list: array of tpm_bank_list structures used to extend the PCR value * * Note: with TPM 2.0 extends also those banks for which no digest was * specified in order to prevent malicious use of those PCR banks. * * Return: same as with tpm_transmit_cmd() */ -int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash) +int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, + const struct tpm_bank_list *bank_list) { int rc; - struct tpm_digest *digest_list; - int i; chip = tpm_find_get_ops(chip); if (!chip) return -ENODEV; if (chip->flags & TPM_CHIP_FLAG_TPM2) { - digest_list = kcalloc(chip->nr_allocated_banks, - sizeof(*digest_list), GFP_KERNEL); - if (!digest_list) - return -ENOMEM; - - for (i = 0; i < chip->nr_allocated_banks; i++) { - digest_list[i].alg_id = chip->allocated_banks[i].alg_id; - memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE); - } - - rc = tpm2_pcr_extend(chip, pcr_idx, chip->nr_allocated_banks, - digest_list); - kfree(digest_list); + rc = tpm2_pcr_extend(chip, pcr_idx, count, bank_list); tpm_put_ops(chip); return rc; } - rc = tpm1_pcr_extend(chip, pcr_idx, hash, + rc = tpm1_pcr_extend(chip, pcr_idx, count, bank_list, "attempting extend a PCR value"); tpm_put_ops(chip); return rc; diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 64d93d26087f..f0cae0892c4e 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -504,8 +504,8 @@ int tpm1_auto_startup(struct tpm_chip *chip); int tpm1_do_selftest(struct tpm_chip *chip); int tpm1_get_timeouts(struct tpm_chip *chip); unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); -int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash, - const char *log_msg); +int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, + const struct tpm_bank_list *bank_list, const char *log_msg); int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf); ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap, const char *desc, size_t min_cap_length); @@ -551,7 +551,7 @@ int tpm2_get_timeouts(struct tpm_chip *chip); int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digest, u16 *digest_size_ptr); int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, - struct tpm_digest *digests); + const struct tpm_bank_list *bank_list); 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); diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c index 8b70a7f884a7..984bacb1a52f 100644 --- a/drivers/char/tpm/tpm1-cmd.c +++ b/drivers/char/tpm/tpm1-cmd.c @@ -449,12 +449,19 @@ int tpm1_get_timeouts(struct tpm_chip *chip) } #define TPM_ORD_PCR_EXTEND 20 -int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash, - const char *log_msg) +int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, + const struct tpm_bank_list *bank_list, const char *log_msg) { struct tpm_buf buf; + u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 }; + const u8 *hash; int rc; + hash = dummy_hash; + if (count) + memcpy(dummy_hash, bank_list[0].extend_array, + min(bank_list[0].extend_size, (u16)sizeof(dummy_hash))); + rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND); if (rc) return rc; @@ -743,7 +750,6 @@ int tpm1_auto_startup(struct tpm_chip *chip) */ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr) { - u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 }; struct tpm_buf buf; unsigned int try; int rc; @@ -751,7 +757,7 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr) /* for buggy tpm, flush pcrs with extend to selected dummy */ if (tpm_suspend_pcr) - rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash, + rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, 0, NULL, "extending dummy pcr before suspend"); rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_SAVESTATE); diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index d6d29480348c..5186277cd981 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -247,21 +247,22 @@ struct tpm2_null_auth_area { * * @chip: TPM chip to use. * @pcr_idx: index of the PCR. - * @count: number of digests passed. - * @digests: list of pcr banks and corresponding digest values to extend. + * @count: number of tpm_bank_list passed. + * @bank_list: array of tpm_bank_list with digest values to extend. * * Return: Same as with tpm_transmit_cmd. */ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, - struct tpm_digest *digests) + const struct tpm_bank_list *bank_list) { struct tpm_buf buf; struct tpm2_null_auth_area auth_area; + const struct tpm_bank_list *item; + u8 dummy_hash[SHA512_DIGEST_SIZE] = { 0 }; + const u8 *hash; int rc; int i; - - if (count > chip->nr_allocated_banks) - return -EINVAL; + int j; rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND); if (rc) @@ -277,11 +278,26 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, tpm_buf_append_u32(&buf, sizeof(struct tpm2_null_auth_area)); tpm_buf_append(&buf, (const unsigned char *)&auth_area, sizeof(auth_area)); - tpm_buf_append_u32(&buf, count); + tpm_buf_append_u32(&buf, chip->nr_allocated_banks); + + if (count) + memcpy(dummy_hash, bank_list[0].extend_array, + bank_list[0].extend_size); + + for (i = 0; i < chip->nr_allocated_banks; i++) { + tpm_buf_append_u16(&buf, chip->allocated_banks[i].alg_id); + + hash = dummy_hash; + for (j = 0; j < count; j++) { + item = bank_list + j; + + if (item->alg_id == chip->allocated_banks[i].alg_id) { + hash = item->extend_array; + break; + } + } - for (i = 0; i < count; i++) { - tpm_buf_append_u16(&buf, digests[i].alg_id); - tpm_buf_append(&buf, (const unsigned char *)&digests[i].digest, + tpm_buf_append(&buf, hash, chip->allocated_banks[i].digest_size); } diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 72df8d4252ef..1b769e558452 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -52,6 +52,12 @@ struct tpm_bank_info { u16 crypto_id; }; +struct tpm_bank_list { + u16 alg_id; + u16 extend_size; + const u8 *extend_array; +}; + enum TPM_OPS_FLAGS { TPM_OPS_AUTO_STARTUP = BIT(0), }; @@ -79,7 +85,8 @@ struct tpm_class_ops { extern int tpm_is_tpm2(struct tpm_chip *chip); extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digest); -extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash); +extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, + const struct tpm_bank_list *bank_list); extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen); extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max); extern int tpm_seal_trusted(struct tpm_chip *chip, @@ -101,8 +108,8 @@ static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, return -ENODEV; } -static inline int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, - const u8 *hash) +static inline int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count, + const struct tpm_bank_list *bank_list) { return -ENODEV; } diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index b186819bd5aa..07c5e26666df 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -140,12 +140,15 @@ unsigned long ima_get_binary_runtime_size(void) static int ima_pcr_extend(const u8 *hash, int pcr) { + struct tpm_bank_list bank_item = { .alg_id = TPM_ALG_SHA1, + .extend_size = TPM_DIGEST_SIZE, + .extend_array = hash }; int result = 0; if (!ima_tpm_chip) return result; - result = tpm_pcr_extend(ima_tpm_chip, pcr, hash); + result = tpm_pcr_extend(ima_tpm_chip, pcr, 1, &bank_item); if (result != 0) pr_err("Error Communicating to TPM chip, result: %d\n", result); return result; diff --git a/security/keys/trusted.c b/security/keys/trusted.c index ff6789365a12..c7d8e6eac4f6 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -380,6 +380,9 @@ EXPORT_SYMBOL_GPL(trusted_tpm_send); static int pcrlock(const int pcrnum) { unsigned char hash[SHA1_DIGEST_SIZE]; + struct tpm_bank_list bank_item = { .alg_id = TPM_ALG_SHA1, + .extend_size = sizeof(hash), + .extend_array = hash }; int ret; if (!capable(CAP_SYS_ADMIN)) @@ -387,7 +390,7 @@ static int pcrlock(const int pcrnum) ret = tpm_get_random(NULL, hash, SHA1_DIGEST_SIZE); if (ret != SHA1_DIGEST_SIZE) return ret; - return tpm_pcr_extend(NULL, pcrnum, hash) ? -EINVAL : 0; + return tpm_pcr_extend(NULL, pcrnum, 1, &bank_item) ? -EINVAL : 0; } /*