2018-09-18 09:41:08

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 00/20] tpm: separate tpm 1.x and tpm 2.x commands

This patch series provides initial separation of tpm 1.x and tpm 2.x
commands, in foresight that the tpm 1.x chips will eventually phase out
and can be compiled out for modern systems.
A new file is added tpm1-cmd.c that contains tpm 1.x specific commands.
In addition, tpm 1.x commands are now implemented using tpm_buf
structure and instead of tpm_cmd_t construct. The latter is now removed.

Note: my tpm 1.x HW availability is limited hence some more testing is needed.

This series also contains two trivial cleanups and addition of new
commands by TCG spec 1.36, now supported on new Intet's platforms.

Tomas Winkler (20):
tpm2: add new tpm2 commands according to TCG 1.36
tpm: sort objects in the Makefile
tpm: factor out tpm 1.x duration calculation to tpm1-cmd.c
tpm: add tpm_calc_ordinal_duration wrapper
tpm: factor out tpm_get_timeouts
tpm: move tpm1_pcr_extend to tpm1-cmd.c
tpm: move tpm_getcap to tpm1-cmd.c
tpm: factor out tpm1_get_random into tpm1-cmd.c
tpm: move tpm1 selftest code from tpm-interface tpm1-cmd.c
tpm: factor out tpm1 pm suspend flow into tpm1-cmd.c
tpm: factor out tpm_startup function
tpm: move pcr extend code to tpm2-cmd.c
tpm: add tpm_auto_startup into tpm-interface
tpm: tpm-interface.c drop unused macros
tpm: tpm-space.c remove unneeded semicolon
tpm: tpm1: rewrite tpm1_get_random() using tpm_buf structure
tpm1: implement tpm1_pcr_read_dev() using tpm_buf structure
tpm: use u32 instead of int for pcr index
tpm1: reimplement SAVESTATE using tpm_buf
tpm1: reimplement tpm1_continue_selftest() using tpm_buf

drivers/char/tpm/Makefile | 16 +-
drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
drivers/char/tpm/tpm-chip.c | 11 +-
drivers/char/tpm/tpm-interface.c | 829 ++---------------------------------
drivers/char/tpm/tpm-sysfs.c | 52 +--
drivers/char/tpm/tpm.h | 98 ++---
drivers/char/tpm/tpm1-cmd.c | 776 ++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm2-cmd.c | 279 ++++++------
drivers/char/tpm/tpm2-space.c | 2 +-
drivers/char/tpm/tpm_i2c_nuvoton.c | 10 +-
drivers/char/tpm/tpm_tis_core.c | 10 +-
include/linux/tpm.h | 2 +-
security/integrity/ima/ima_crypto.c | 5 +-
13 files changed, 1061 insertions(+), 1031 deletions(-)
create mode 100644 drivers/char/tpm/tpm1-cmd.c

--
2.14.4



2018-09-18 09:38:35

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 02/20] tpm: sort objects in the Makefile

Make the tpm Makefile a bit more in order by putting
objects in one column and group together tpm2 modules

Signed-off-by: Tomas Winkler <[email protected]>
---
V2: 1. back to tpm-y notation
2. Partially sort files alphanumerically.
V3: Rebase

drivers/char/tpm/Makefile | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 4e9c33ca1f8f..efc785053627 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -3,9 +3,18 @@
# Makefile for the kernel tpm device drivers.
#
obj-$(CONFIG_TCG_TPM) += tpm.o
-tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
- tpm-dev-common.o tpmrm-dev.o eventlog/common.o eventlog/tpm1.o \
- eventlog/tpm2.o tpm2-space.o
+tpm-y := tpm-chip.o
+tpm-y += tpm-dev-common.o
+tpm-y += tpm-dev.o
+tpm-y += tpm-interface.o
+tpm-y += tpm2-cmd.o
+tpm-y += tpmrm-dev.o
+tpm-y += tpm2-space.o
+tpm-y += tpm-sysfs.o
+tpm-y += eventlog/common.o
+tpm-y += eventlog/tpm1.o
+tpm-y += eventlog/tpm2.o
+
tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
tpm-$(CONFIG_EFI) += eventlog/efi.o
tpm-$(CONFIG_OF) += eventlog/of.o
--
2.14.4


2018-09-18 09:39:05

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 03/20] tpm: factor out tpm 1.x duration calculation to tpm1-cmd.c

Factor out tpm 1.x commands calculation into tpm1-cmd.c file.
and change the prefix from tpm_ to tpm1_.
No functional change is done here.

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase
drivers/char/tpm/Makefile | 1 +
drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
drivers/char/tpm/tpm-interface.c | 284 +-------------------------------
drivers/char/tpm/tpm.h | 2 +-
drivers/char/tpm/tpm1-cmd.c | 310 +++++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm_i2c_nuvoton.c | 10 +-
drivers/char/tpm/tpm_tis_core.c | 2 +-
drivers/char/tpm/xen-tpmfront.c | 2 +-
8 files changed, 322 insertions(+), 291 deletions(-)
create mode 100644 drivers/char/tpm/tpm1-cmd.c

diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index efc785053627..a01c4cab902a 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -7,6 +7,7 @@ tpm-y := tpm-chip.o
tpm-y += tpm-dev-common.o
tpm-y += tpm-dev.o
tpm-y += tpm-interface.o
+tpm-y += tpm1-cmd.o
tpm-y += tpm2-cmd.o
tpm-y += tpmrm-dev.o
tpm-y += tpm2-space.o
diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
index abd675bec88c..16be974955ea 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -430,7 +430,7 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));

ret = wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- tpm_calc_ordinal_duration(chip, ordinal),
+ tpm1_calc_ordinal_duration(chip, ordinal),
&tpm_dev->read_queue, false);
if (ret < 0)
goto out_err;
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 129f640424b7..bb3eed907c72 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -33,7 +33,6 @@

#include "tpm.h"

-#define TPM_MAX_ORDINAL 243
#define TSC_MAX_ORDINAL 12
#define TPM_PROTECTED_COMMAND 0x00
#define TPM_CONNECTION_COMMAND 0x40
@@ -48,285 +47,6 @@ module_param_named(suspend_pcr, tpm_suspend_pcr, uint, 0644);
MODULE_PARM_DESC(suspend_pcr,
"PCR to use for dummy writes to facilitate flush on suspend.");

-/*
- * Array with one entry per ordinal defining the maximum amount
- * of time the chip could take to return the result. The ordinal
- * designation of short, medium or long is defined in a table in
- * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
- * values of the SHORT, MEDIUM, and LONG durations are retrieved
- * from the chip during initialization with a call to tpm_get_timeouts.
- */
-static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
- TPM_UNDEFINED, /* 0 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 5 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 10 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_LONG,
- TPM_MEDIUM, /* 15 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_SHORT, /* 20 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT, /* 25 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 30 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 35 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 40 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 45 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_LONG,
- TPM_MEDIUM, /* 50 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 55 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 60 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 65 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 70 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 75 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 80 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
- TPM_LONG,
- TPM_SHORT,
- TPM_UNDEFINED, /* 85 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 90 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 95 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 100 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 105 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 110 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 115 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 120 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 125 */
- TPM_SHORT,
- TPM_LONG,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT, /* 130 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_UNDEFINED, /* 135 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 140 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 145 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 150 */
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 155 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 160 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 165 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_LONG, /* 170 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 175 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_MEDIUM, /* 180 */
- TPM_SHORT,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM, /* 185 */
- TPM_SHORT,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 190 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 195 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 200 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 205 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_MEDIUM, /* 210 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_MEDIUM,
- TPM_UNDEFINED, /* 215 */
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT,
- TPM_SHORT, /* 220 */
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_SHORT,
- TPM_UNDEFINED, /* 225 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 230 */
- TPM_LONG,
- TPM_MEDIUM,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED, /* 235 */
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_UNDEFINED,
- TPM_SHORT, /* 240 */
- TPM_UNDEFINED,
- TPM_MEDIUM,
-};
-
-/*
- * Returns max number of jiffies to wait
- */
-unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
- u32 ordinal)
-{
- int duration_idx = TPM_UNDEFINED;
- int duration = 0;
-
- /*
- * We only have a duration table for protected commands, where the upper
- * 16 bits are 0. For the few other ordinals the fallback will be used.
- */
- if (ordinal < TPM_MAX_ORDINAL)
- duration_idx = tpm_ordinal_duration[ordinal];
-
- if (duration_idx != TPM_UNDEFINED)
- duration = chip->duration[duration_idx];
- if (duration <= 0)
- return 2 * 60 * HZ;
- else
- return duration;
-}
-EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
-
static int tpm_validate_command(struct tpm_chip *chip,
struct tpm_space *space,
const u8 *cmd,
@@ -503,7 +223,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
if (chip->flags & TPM_CHIP_FLAG_TPM2)
stop = jiffies + tpm2_calc_ordinal_duration(chip, ordinal);
else
- stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
+ stop = jiffies + tpm1_calc_ordinal_duration(chip, ordinal);
do {
u8 status = chip->ops->status(chip);
if ((status & chip->ops->req_complete_mask) ==
@@ -1086,7 +806,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
unsigned long duration;
u8 dummy[TPM_DIGEST_SIZE];

- duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);
+ duration = tpm1_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);

loops = jiffies_to_msecs(duration) / delay_msec;

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 0f08518b525d..c59d2c20c339 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -546,7 +546,7 @@ ssize_t tpm_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
int tpm_get_timeouts(struct tpm_chip *);
int tpm1_auto_startup(struct tpm_chip *chip);
int tpm_do_selftest(struct tpm_chip *chip);
-unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
+unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);

diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
new file mode 100644
index 000000000000..fa6ba8d3458c
--- /dev/null
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2004 IBM Corporation
+ * Copyright (C) 2014 Intel Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <[email protected]>
+ * Dave Safford <[email protected]>
+ * Reiner Sailer <[email protected]>
+ * Kylene Hall <[email protected]>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at http://www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/freezer.h>
+#include <linux/tpm_eventlog.h>
+
+#include "tpm.h"
+
+#define TPM_MAX_ORDINAL 243
+
+/*
+ * Array with one entry per ordinal defining the maximum amount
+ * of time the chip could take to return the result. The ordinal
+ * designation of short, medium or long is defined in a table in
+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
+ * from the chip during initialization with a call to tpm_get_timeouts.
+ */
+static const u8 tpm1_ordinal_duration[TPM_MAX_ORDINAL] = {
+ TPM_UNDEFINED, /* 0 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 5 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 10 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_LONG,
+ TPM_MEDIUM, /* 15 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_SHORT, /* 20 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT, /* 25 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 30 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 35 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 40 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 45 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_LONG,
+ TPM_MEDIUM, /* 50 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 55 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 60 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 65 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 70 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 75 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 80 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+ TPM_LONG,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 85 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 90 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 95 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 100 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 105 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 110 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 115 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 120 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 125 */
+ TPM_SHORT,
+ TPM_LONG,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT, /* 130 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_UNDEFINED, /* 135 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 140 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 145 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 150 */
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 155 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 160 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 165 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_LONG, /* 170 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 175 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_MEDIUM, /* 180 */
+ TPM_SHORT,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM, /* 185 */
+ TPM_SHORT,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 190 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 195 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 200 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 205 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_MEDIUM, /* 210 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_MEDIUM,
+ TPM_UNDEFINED, /* 215 */
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT,
+ TPM_SHORT, /* 220 */
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_SHORT,
+ TPM_UNDEFINED, /* 225 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 230 */
+ TPM_LONG,
+ TPM_MEDIUM,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED, /* 235 */
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_UNDEFINED,
+ TPM_SHORT, /* 240 */
+ TPM_UNDEFINED,
+ TPM_MEDIUM,
+};
+
+/*
+ * Returns max number of jiffies to wait
+ */
+unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+{
+ int duration_idx = TPM_UNDEFINED;
+ int duration = 0;
+
+ /*
+ * We only have a duration table for protected commands, where the upper
+ * 16 bits are 0. For the few other ordinals the fallback will be used.
+ */
+ if (ordinal < TPM_MAX_ORDINAL)
+ duration_idx = tpm1_ordinal_duration[ordinal];
+
+ if (duration_idx != TPM_UNDEFINED)
+ duration = chip->duration[duration_idx];
+ if (duration <= 0)
+ return 2 * 60 * HZ;
+ else
+ return duration;
+}
+EXPORT_SYMBOL_GPL(tpm1_calc_ordinal_duration);
+
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
index caa86b19c76d..5d20e98b844f 100644
--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -370,6 +370,7 @@ static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
struct i2c_client *client = to_i2c_client(dev);
u32 ordinal;
size_t count = 0;
+ unsigned long duration;
int burst_count, bytes2write, retries, rc = -EIO;

for (retries = 0; retries < TPM_RETRY; retries++) {
@@ -455,12 +456,11 @@ static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
return rc;
}
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
- rc = i2c_nuvoton_wait_for_data_avail(chip,
- tpm_calc_ordinal_duration(chip,
- ordinal),
- &priv->read_queue);
+ duration = tpm1_calc_ordinal_duration(chip, ordinal);
+ rc = i2c_nuvoton_wait_for_data_avail(chip, duration, &priv->read_queue);
if (rc) {
- dev_err(dev, "%s() timeout command duration\n", __func__);
+ dev_err(dev, "%s() timeout command duration %ld\n",
+ __func__, duration);
i2c_nuvoton_ready(chip);
return rc;
}
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index d2345d9fd7b5..14c332104de4 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -476,7 +476,7 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
if (chip->flags & TPM_CHIP_FLAG_TPM2)
dur = tpm2_calc_ordinal_duration(chip, ordinal);
else
- dur = tpm_calc_ordinal_duration(chip, ordinal);
+ dur = tpm1_calc_ordinal_duration(chip, ordinal);

if (wait_for_tpm_stat
(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, dur,
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
index 911475d36800..c7ded298617d 100644
--- a/drivers/char/tpm/xen-tpmfront.c
+++ b/drivers/char/tpm/xen-tpmfront.c
@@ -164,7 +164,7 @@ static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
notify_remote_via_evtchn(priv->evtchn);

ordinal = be32_to_cpu(((struct tpm_input_header*)buf)->ordinal);
- duration = tpm_calc_ordinal_duration(chip, ordinal);
+ duration = tpm1_calc_ordinal_duration(chip, ordinal);

if (wait_for_tpm_stat(chip, VTPM_STATUS_IDLE, duration,
&priv->read_queue, true) < 0) {
--
2.14.4


2018-09-18 09:39:19

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 15/20] tpm: tpm-space.c remove unneeded semicolon

Remove unneeded semicolon in tpm2_map_response_header()

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series
drivers/char/tpm/tpm2-space.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index d2e101b32482..dcdfde3c253e 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -373,7 +373,7 @@ static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,
dev_err(&chip->dev, "%s: unknown handle 0x%08X\n",
__func__, phandle);
break;
- };
+ }

return 0;
out_no_slots:
--
2.14.4


2018-09-18 09:39:31

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 19/20] tpm1: reimplement SAVESTATE using tpm_buf

In tpm1_pm_suspend() function reimplement,
TPM_ORD_SAVESTATE comamnd using tpm_buf.

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series

drivers/char/tpm/tpm1-cmd.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 777b1158e1b5..c4a0bacb1378 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -719,12 +719,6 @@ int tpm1_auto_startup(struct tpm_chip *chip)
}

#define TPM_ORD_SAVESTATE 152
-#define SAVESTATE_RESULT_SIZE 10
-static const struct tpm_input_header savestate_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(10),
- .ordinal = cpu_to_be32(TPM_ORD_SAVESTATE)
-};

/*
* We are about to suspend. Save the TPM state
@@ -733,18 +727,22 @@ static const struct tpm_input_header savestate_header = {
int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
{
u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
- struct tpm_cmd_t cmd;
- int rc, try;
+ struct tpm_buf buf;
+ unsigned int try;
+ int rc;
+

/* for buggy tpm, flush pcrs with extend to selected dummy */
if (tpm_suspend_pcr)
rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash,
"extending dummy pcr before suspend");

+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_SAVESTATE);
+ if (rc)
+ return rc;
/* now do the actual savestate */
for (try = 0; try < TPM_RETRY; try++) {
- cmd.header.in = savestate_header;
- rc = tpm_transmit_cmd(chip, NULL, &cmd, SAVESTATE_RESULT_SIZE,
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
0, 0, NULL);

/*
@@ -760,6 +758,8 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
if (rc != TPM_WARN_RETRY)
break;
tpm_msleep(TPM_TIMEOUT_RETRY);
+
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_SAVESTATE);
}

if (rc)
@@ -769,6 +769,8 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
dev_warn(&chip->dev, "TPM savestate took %dms\n",
try * TPM_TIMEOUT_RETRY);

+ tpm_buf_destroy(&buf);
+
return rc;
}

--
2.14.4


2018-09-18 09:39:36

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 18/20] tpm: use u32 instead of int for pcr index

TPM pcr indices cannot be negative, also the tpm
commands accept u32 number as a pcr index.

1. Adjust the API to use u32 instead of int in all pcr related
functions.
2. Rename tpm1_pcr_read_dev to tpm1_pcr_read() to match
the counterpart tpm2_pcr_read()
3. Remove redundant constants in tpm1_pcr_extend() function.

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series
drivers/char/tpm/tpm-interface.c | 4 ++--
drivers/char/tpm/tpm-sysfs.c | 4 ++--
drivers/char/tpm/tpm.h | 10 +++++-----
drivers/char/tpm/tpm1-cmd.c | 14 ++++++--------
drivers/char/tpm/tpm2-cmd.c | 6 +++---
include/linux/tpm.h | 2 +-
security/integrity/ima/ima_crypto.c | 5 +++--
7 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index e3206874be22..0eea784e1ae4 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -444,7 +444,7 @@ EXPORT_SYMBOL_GPL(tpm_is_tpm2);
*
* Return: same as with tpm_transmit_cmd()
*/
-int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
{
int rc;

@@ -455,7 +455,7 @@ int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
if (chip->flags & TPM_CHIP_FLAG_TPM2)
rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
else
- rc = tpm1_pcr_read_dev(chip, pcr_idx, res_buf);
+ rc = tpm1_pcr_read(chip, pcr_idx, res_buf);

tpm_put_ops(chip);
return rc;
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 861acafd8f29..b88e08ec2c59 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -102,7 +102,7 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
cap_t cap;
u8 digest[TPM_DIGEST_SIZE];
ssize_t rc;
- int i, j, num_pcrs;
+ u32 i, j, num_pcrs;
char *str = buf;
struct tpm_chip *chip = to_tpm_chip(dev);

@@ -114,7 +114,7 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,

num_pcrs = be32_to_cpu(cap.num_pcrs);
for (i = 0; i < num_pcrs; i++) {
- rc = tpm1_pcr_read_dev(chip, i, digest);
+ rc = tpm1_pcr_read(chip, i, digest);
if (rc)
break;
str += sprintf(str, "PCR-%02d: ", i);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index d0402aa122ec..dbbfb7118c31 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -518,14 +518,14 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
int tpm_get_timeouts(struct tpm_chip *);
int tpm_auto_startup(struct tpm_chip *chip);

-int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr);
+int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr);
int tpm1_do_selftest(struct tpm_chip *chip);
int tpm1_auto_startup(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, int pcr_idx, const u8 *hash,
+int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
const char *log_msg);
-int tpm1_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
+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);
int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max);
@@ -567,8 +567,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, int pcr_idx, u8 *res_buf);
-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
+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, const u8 *hash);
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 e81641f9d0e3..777b1158e1b5 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -449,9 +449,7 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
}

#define TPM_ORD_PCR_EXTEND 20
-#define EXTEND_PCR_RESULT_SIZE 34
-#define EXTEND_PCR_RESULT_BODY_SIZE 20
-int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,
+int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
const char *log_msg)
{
struct tpm_buf buf;
@@ -464,8 +462,8 @@ int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,
tpm_buf_append_u32(&buf, pcr_idx);
tpm_buf_append(&buf, hash, TPM_DIGEST_SIZE);

- rc = tpm_transmit_cmd(chip, NULL, buf.data, EXTEND_PCR_RESULT_SIZE,
- EXTEND_PCR_RESULT_BODY_SIZE, 0, log_msg);
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ TPM_DIGEST_SIZE, 0, log_msg);

tpm_buf_destroy(&buf);
return rc;
@@ -575,7 +573,7 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
}

#define TPM_ORD_PCRREAD 21
-int tpm1_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
{
struct tpm_buf buf;
int rc;
@@ -663,7 +661,7 @@ int tpm1_do_selftest(struct tpm_chip *chip)

do {
/* Attempt to read a PCR value */
- rc = tpm1_pcr_read_dev(chip, 0, dummy);
+ rc = tpm1_pcr_read(chip, 0, dummy);

/* Some buggy TPMs will not respond to tpm_tis_ready() for
* around 300ms while the self test is ongoing, keep trying
@@ -732,7 +730,7 @@ static const struct tpm_input_header savestate_header = {
* We are about to suspend. Save the TPM state
* so that it can be restored.
*/
-int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr)
+int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
{
u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
struct tpm_cmd_t cmd;
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index b0b714309440..c2f297140dc7 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -128,7 +128,7 @@ struct tpm2_pcr_read_out {
*
* Return: Same as with tpm_transmit_cmd.
*/
-int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
{
int rc;
struct tpm_buf buf;
@@ -178,7 +178,7 @@ struct tpm2_null_auth_area {
*
* Return: Same as with tpm_transmit_cmd.
*/
-static int __tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
+static int __tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count,
struct tpm2_digest *digests)
{
struct tpm_buf buf;
@@ -225,7 +225,7 @@ static int __tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
return rc;
}

-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash)
{
int rc;
struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)];
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 4609b94142d4..44c13cdf720a 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -53,7 +53,7 @@ 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, int pcr_idx, u8 *res_buf);
+int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
extern int tpm_pcr_extend(struct tpm_chip *chip, int 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);
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 7e7e7e7c250a..959d9edc113a 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -629,7 +629,7 @@ int ima_calc_buffer_hash(const void *buf, loff_t len,
return calc_buffer_shash(buf, len, hash);
}

-static void __init ima_pcrread(int idx, u8 *pcr)
+static void __init ima_pcrread(u32 idx, u8 *pcr)
{
if (!ima_tpm_chip)
return;
@@ -645,7 +645,8 @@ static int __init ima_calc_boot_aggregate_tfm(char *digest,
struct crypto_shash *tfm)
{
u8 pcr_i[TPM_DIGEST_SIZE];
- int rc, i;
+ int rc;
+ u32 i;
SHASH_DESC_ON_STACK(shash, tfm);

shash->tfm = tfm;
--
2.14.4


2018-09-18 09:39:43

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 16/20] tpm: tpm1: rewrite tpm1_get_random() using tpm_buf structure

1. Use tpm_buf in tpm1_get_random()
2. Fix comment in tpm_get_random() so it is clear that
the function is expected to return number of random bytes.

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series
drivers/char/tpm/tpm-interface.c | 2 +-
drivers/char/tpm/tpm.h | 11 ------
drivers/char/tpm/tpm1-cmd.c | 85 +++++++++++++++++++++++-----------------
3 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 358ef5bd601e..e3206874be22 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -576,7 +576,7 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
* @out: destination buffer for the random bytes
* @max: the max number of bytes to write to @out
*
- * Return: same as with tpm_transmit_cmd()
+ * Return: number of random bytes read or a negative error value.
*/
int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
{
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 4ccffbb56864..d6eca81a011a 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -396,20 +396,9 @@ struct tpm_pcrread_in {
* compiler warnings about stack frame size. */
#define TPM_MAX_RNG_DATA 128

-struct tpm_getrandom_out {
- __be32 rng_data_len;
- u8 rng_data[TPM_MAX_RNG_DATA];
-} __packed;
-
-struct tpm_getrandom_in {
- __be32 num_bytes;
-} __packed;
-
typedef union {
struct tpm_pcrread_in pcrread_in;
struct tpm_pcrread_out pcrread_out;
- struct tpm_getrandom_in getrandom_in;
- struct tpm_getrandom_out getrandom_out;
} tpm_cmd_params;

struct tpm_cmd_t {
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 90e5bc1720ad..5708d4bf908f 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -507,58 +507,71 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
EXPORT_SYMBOL_GPL(tpm1_getcap);

#define TPM_ORD_GET_RANDOM 70
-#define TPM_GETRANDOM_RESULT_SIZE 18
-static const struct tpm_input_header tpm_getrandom_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(14),
- .ordinal = cpu_to_be32(TPM_ORD_GET_RANDOM)
-};
+struct tpm1_get_random_out {
+ __be32 rng_data_len;
+ u8 rng_data[TPM_MAX_RNG_DATA];
+} __packed;

-int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max)
+/**
+ * tpm1_get_random() - get random bytes from the TPM's RNG
+ *
+ * @chip: a &struct tpm_chip instance
+ * @dest: destination buffer for the random bytes
+ * @max: the maximum number of bytes to write to @dest
+ *
+ * Return:
+ * number of bytes read
+ * -errno or a TPM return code otherwise
+ */
+int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
{
- struct tpm_cmd_t tpm_cmd;
+ struct tpm1_get_random_out *out;
+ u32 num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
+ struct tpm_buf buf;
+ u32 total = 0;
+ int retries = 5;
u32 recd;
- u32 num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
- u32 rlength;
- int err, total = 0, retries = 5;
- u8 *dest = out;
+ int rc;

- if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
- return -EINVAL;
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
+ if (rc)
+ return rc;

do {
- tpm_cmd.header.in = tpm_getrandom_header;
- tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
-
- err = tpm_transmit_cmd(chip, NULL, &tpm_cmd,
- TPM_GETRANDOM_RESULT_SIZE + num_bytes,
- offsetof(struct tpm_getrandom_out,
- rng_data),
- 0, "attempting get random");
- if (err)
- break;
+ tpm_buf_append_u32(&buf, num_bytes);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ sizeof(out->rng_data_len), 0,
+ "attempting get random");
+ if (rc)
+ goto out;

- recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
+ out = (struct tpm1_get_random_out *)&buf.data[TPM_HEADER_SIZE];
+
+ recd = be32_to_cpu(out->rng_data_len);
if (recd > num_bytes) {
- total = -EFAULT;
- break;
+ rc = -EFAULT;
+ goto out;
}

- rlength = be32_to_cpu(tpm_cmd.header.out.length);
- if (rlength < TPM_HEADER_SIZE +
- offsetof(struct tpm_getrandom_out, rng_data) +
- recd) {
- total = -EFAULT;
- break;
+ if (tpm_buf_length(&buf) < TPM_HEADER_SIZE +
+ sizeof(out->rng_data_len) + recd) {
+ rc = -EFAULT;
+ goto out;
}
- memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
+ memcpy(dest, out->rng_data, recd);

dest += recd;
total += recd;
num_bytes -= recd;
- } while (retries-- && (size_t)total < max);

- return total ? total : -EIO;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
+ } while (retries-- && total < max);
+
+ rc = total ? total : -EIO;
+out:
+ tpm_buf_destroy(&buf);
+ return rc;
}

#define TPM_ORDINAL_PCRREAD 21
--
2.14.4


2018-09-18 09:39:47

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 01/20] tpm2: add new tpm2 commands according to TCG 1.36

1. TPM2_CC_LAST has moved from 182 to 193
2. Convert tpm2_ordinal_duration from an array into a switch statement,
as there are not so many commands that require special duration
relative to a number of commands.

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase.
drivers/char/tpm/tpm.h | 41 +++++----
drivers/char/tpm/tpm2-cmd.c | 196 +++++++++++++++-----------------------------
2 files changed, 93 insertions(+), 144 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index f20dc8ece348..0f08518b525d 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -134,22 +134,31 @@ enum tpm2_algorithms {
};

enum tpm2_command_codes {
- TPM2_CC_FIRST = 0x011F,
- TPM2_CC_CREATE_PRIMARY = 0x0131,
- TPM2_CC_SELF_TEST = 0x0143,
- TPM2_CC_STARTUP = 0x0144,
- TPM2_CC_SHUTDOWN = 0x0145,
- TPM2_CC_CREATE = 0x0153,
- TPM2_CC_LOAD = 0x0157,
- TPM2_CC_UNSEAL = 0x015E,
- TPM2_CC_CONTEXT_LOAD = 0x0161,
- TPM2_CC_CONTEXT_SAVE = 0x0162,
- TPM2_CC_FLUSH_CONTEXT = 0x0165,
- TPM2_CC_GET_CAPABILITY = 0x017A,
- TPM2_CC_GET_RANDOM = 0x017B,
- TPM2_CC_PCR_READ = 0x017E,
- TPM2_CC_PCR_EXTEND = 0x0182,
- TPM2_CC_LAST = 0x018F,
+ TPM2_CC_FIRST = 0x011F,
+ TPM2_CC_HIERARCHY_CONTROL = 0x0121,
+ TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129,
+ TPM2_CC_CREATE_PRIMARY = 0x0131,
+ TPM2_CC_SEQUENCE_COMPLETE = 0x013E,
+ TPM2_CC_SELF_TEST = 0x0143,
+ TPM2_CC_STARTUP = 0x0144,
+ TPM2_CC_SHUTDOWN = 0x0145,
+ TPM2_CC_NV_READ = 0x014E,
+ TPM2_CC_CREATE = 0x0153,
+ TPM2_CC_LOAD = 0x0157,
+ TPM2_CC_SEQUENCE_UPDATE = 0x015C,
+ TPM2_CC_UNSEAL = 0x015E,
+ TPM2_CC_CONTEXT_LOAD = 0x0161,
+ TPM2_CC_CONTEXT_SAVE = 0x0162,
+ TPM2_CC_FLUSH_CONTEXT = 0x0165,
+ TPM2_CC_VERIFY_SIGNATURE = 0x0177,
+ TPM2_CC_GET_CAPABILITY = 0x017A,
+ TPM2_CC_GET_RANDOM = 0x017B,
+ TPM2_CC_PCR_READ = 0x017E,
+ TPM2_CC_PCR_EXTEND = 0x0182,
+ TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
+ TPM2_CC_HASH_SEQUENCE_START = 0x0186,
+ TPM2_CC_CREATE_LOADED = 0x0191,
+ TPM2_CC_LAST = 0x0193, /* Spec 1.36 */
};

enum tpm2_permanent_handles {
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 3acf4fd4e5a5..9c3c5c0628d9 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -41,128 +41,73 @@ static struct tpm2_hash tpm2_hash_map[] = {
};

/*
- * Array with one entry per ordinal defining the maximum amount
+ * tpm2_ordinal_duration returns the maximum amount
* of time the chip could take to return the result. The values
- * of the SHORT, MEDIUM, and LONG durations are taken from the
- * PC Client Profile (PTP) specification.
+ * of the MEDIUM, and LONG durations are taken from the
+ * PC Client Profile (PTP) specification (750, 2000 msec)
+ *
* LONG_LONG is for commands that generates keys which empirically
* takes longer time on some systems.
*/
-static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = {
- TPM_UNDEFINED, /* 11F */
- TPM_UNDEFINED, /* 120 */
- TPM_LONG, /* 121 */
- TPM_UNDEFINED, /* 122 */
- TPM_UNDEFINED, /* 123 */
- TPM_UNDEFINED, /* 124 */
- TPM_UNDEFINED, /* 125 */
- TPM_UNDEFINED, /* 126 */
- TPM_UNDEFINED, /* 127 */
- TPM_UNDEFINED, /* 128 */
- TPM_LONG, /* 129 */
- TPM_UNDEFINED, /* 12a */
- TPM_UNDEFINED, /* 12b */
- TPM_UNDEFINED, /* 12c */
- TPM_UNDEFINED, /* 12d */
- TPM_UNDEFINED, /* 12e */
- TPM_UNDEFINED, /* 12f */
- TPM_UNDEFINED, /* 130 */
- TPM_LONG_LONG, /* 131 */
- TPM_UNDEFINED, /* 132 */
- TPM_UNDEFINED, /* 133 */
- TPM_UNDEFINED, /* 134 */
- TPM_UNDEFINED, /* 135 */
- TPM_UNDEFINED, /* 136 */
- TPM_UNDEFINED, /* 137 */
- TPM_UNDEFINED, /* 138 */
- TPM_UNDEFINED, /* 139 */
- TPM_UNDEFINED, /* 13a */
- TPM_UNDEFINED, /* 13b */
- TPM_UNDEFINED, /* 13c */
- TPM_UNDEFINED, /* 13d */
- TPM_MEDIUM, /* 13e */
- TPM_UNDEFINED, /* 13f */
- TPM_UNDEFINED, /* 140 */
- TPM_UNDEFINED, /* 141 */
- TPM_UNDEFINED, /* 142 */
- TPM_LONG, /* 143 */
- TPM_MEDIUM, /* 144 */
- TPM_UNDEFINED, /* 145 */
- TPM_UNDEFINED, /* 146 */
- TPM_UNDEFINED, /* 147 */
- TPM_UNDEFINED, /* 148 */
- TPM_UNDEFINED, /* 149 */
- TPM_UNDEFINED, /* 14a */
- TPM_UNDEFINED, /* 14b */
- TPM_UNDEFINED, /* 14c */
- TPM_UNDEFINED, /* 14d */
- TPM_LONG, /* 14e */
- TPM_UNDEFINED, /* 14f */
- TPM_UNDEFINED, /* 150 */
- TPM_UNDEFINED, /* 151 */
- TPM_UNDEFINED, /* 152 */
- TPM_LONG_LONG, /* 153 */
- TPM_UNDEFINED, /* 154 */
- TPM_UNDEFINED, /* 155 */
- TPM_UNDEFINED, /* 156 */
- TPM_UNDEFINED, /* 157 */
- TPM_UNDEFINED, /* 158 */
- TPM_UNDEFINED, /* 159 */
- TPM_UNDEFINED, /* 15a */
- TPM_UNDEFINED, /* 15b */
- TPM_MEDIUM, /* 15c */
- TPM_UNDEFINED, /* 15d */
- TPM_UNDEFINED, /* 15e */
- TPM_UNDEFINED, /* 15f */
- TPM_UNDEFINED, /* 160 */
- TPM_UNDEFINED, /* 161 */
- TPM_UNDEFINED, /* 162 */
- TPM_UNDEFINED, /* 163 */
- TPM_UNDEFINED, /* 164 */
- TPM_UNDEFINED, /* 165 */
- TPM_UNDEFINED, /* 166 */
- TPM_UNDEFINED, /* 167 */
- TPM_UNDEFINED, /* 168 */
- TPM_UNDEFINED, /* 169 */
- TPM_UNDEFINED, /* 16a */
- TPM_UNDEFINED, /* 16b */
- TPM_UNDEFINED, /* 16c */
- TPM_UNDEFINED, /* 16d */
- TPM_UNDEFINED, /* 16e */
- TPM_UNDEFINED, /* 16f */
- TPM_UNDEFINED, /* 170 */
- TPM_UNDEFINED, /* 171 */
- TPM_UNDEFINED, /* 172 */
- TPM_UNDEFINED, /* 173 */
- TPM_UNDEFINED, /* 174 */
- TPM_UNDEFINED, /* 175 */
- TPM_UNDEFINED, /* 176 */
- TPM_LONG, /* 177 */
- TPM_UNDEFINED, /* 178 */
- TPM_UNDEFINED, /* 179 */
- TPM_MEDIUM, /* 17a */
- TPM_LONG, /* 17b */
- TPM_UNDEFINED, /* 17c */
- TPM_UNDEFINED, /* 17d */
- TPM_UNDEFINED, /* 17e */
- TPM_UNDEFINED, /* 17f */
- TPM_UNDEFINED, /* 180 */
- TPM_UNDEFINED, /* 181 */
- TPM_MEDIUM, /* 182 */
- TPM_UNDEFINED, /* 183 */
- TPM_UNDEFINED, /* 184 */
- TPM_MEDIUM, /* 185 */
- TPM_MEDIUM, /* 186 */
- TPM_UNDEFINED, /* 187 */
- TPM_UNDEFINED, /* 188 */
- TPM_UNDEFINED, /* 189 */
- TPM_UNDEFINED, /* 18a */
- TPM_UNDEFINED, /* 18b */
- TPM_UNDEFINED, /* 18c */
- TPM_UNDEFINED, /* 18d */
- TPM_UNDEFINED, /* 18e */
- TPM_UNDEFINED /* 18f */
-};
+static u8 tpm2_ordinal_duration(u32 ordinal)
+{
+ switch (ordinal) {
+ /* Startup */
+ case TPM2_CC_STARTUP: /* 144 */
+ return TPM_MEDIUM;
+
+ /* Selftest */
+ case TPM2_CC_SELF_TEST: /* 143 */
+ return TPM_LONG;
+
+ /* Random Number Generator */
+ case TPM2_CC_GET_RANDOM: /* 17B */
+ return TPM_LONG;
+
+ /* Hash/HMAC/Event Sequences */
+ case TPM2_CC_SEQUENCE_UPDATE: /* 15C */
+ return TPM_MEDIUM;
+ case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */
+ return TPM_MEDIUM;
+ case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */
+ return TPM_MEDIUM;
+ case TPM2_CC_HASH_SEQUENCE_START: /* 186 */
+ return TPM_MEDIUM;
+
+ /* Signature Verification */
+ case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
+ return TPM_LONG;
+
+ /* Integrity Collection (PCR) */
+ case TPM2_CC_PCR_EXTEND: /* 182 */
+ return TPM_MEDIUM;
+
+ /* Hierarchy Commands */
+ case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
+ return TPM_LONG;
+ case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
+ return TPM_LONG;
+
+ /* Capability Commands */
+ case TPM2_CC_GET_CAPABILITY: /* 17A */
+ return TPM_MEDIUM;
+
+ /* Non-volatile Storage */
+ case TPM2_CC_NV_READ: /* 14E */
+ return TPM_LONG;
+
+ /* Key generation (not in PTP) */
+ case TPM2_CC_CREATE_PRIMARY: /* 131 */
+ return TPM_LONG_LONG;
+ case TPM2_CC_CREATE: /* 153 */
+ return TPM_LONG_LONG;
+ case TPM2_CC_CREATE_LOADED: /* 191 */
+ return TPM_LONG_LONG;
+
+ default:
+ return TPM_UNDEFINED;
+ }
+}

struct tpm2_pcr_read_out {
__be32 update_cnt;
@@ -758,19 +703,14 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
*/
unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
{
- int index = TPM_UNDEFINED;
- int duration = 0;
+ unsigned int index;

- if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST)
- index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST];
+ index = tpm2_ordinal_duration(ordinal);

if (index != TPM_UNDEFINED)
- duration = chip->duration[index];
-
- if (duration <= 0)
- duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT);
-
- return duration;
+ return chip->duration[index];
+ else
+ return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
}
EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);

--
2.14.4


2018-09-18 09:39:53

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 05/20] tpm: factor out tpm_get_timeouts

Factor out tpm_get_timeouts into tpm2_get_timeouts
and tpm1_get_timeouts.

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase
drivers/char/tpm/tpm-interface.c | 127 ++-------------------------------------
drivers/char/tpm/tpm.h | 5 +-
drivers/char/tpm/tpm1-cmd.c | 106 ++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm2-cmd.c | 22 +++++++
4 files changed, 136 insertions(+), 124 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 7b460f646781..55f9094a8f11 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -492,132 +492,13 @@ EXPORT_SYMBOL_GPL(tpm_getcap);

int tpm_get_timeouts(struct tpm_chip *chip)
{
- cap_t cap;
- unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
- ssize_t rc;
-
if (chip->flags & TPM_CHIP_FLAG_HAVE_TIMEOUTS)
return 0;

- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
- /* Fixed timeouts for TPM2 */
- chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
- chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
- chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
- chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
- chip->duration[TPM_SHORT] =
- msecs_to_jiffies(TPM2_DURATION_SHORT);
- chip->duration[TPM_MEDIUM] =
- msecs_to_jiffies(TPM2_DURATION_MEDIUM);
- chip->duration[TPM_LONG] =
- msecs_to_jiffies(TPM2_DURATION_LONG);
- chip->duration[TPM_LONG_LONG] =
- msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
-
- chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
- return 0;
- }
-
- rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, NULL,
- sizeof(cap.timeout));
- if (rc == TPM_ERR_INVALID_POSTINIT) {
- if (tpm_startup(chip))
- return rc;
-
- rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap,
- "attempting to determine the timeouts",
- sizeof(cap.timeout));
- }
-
- if (rc) {
- dev_err(&chip->dev,
- "A TPM error (%zd) occurred attempting to determine the timeouts\n",
- rc);
- return rc;
- }
-
- timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
- timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
- timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
- timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
- timeout_chip[0] = be32_to_cpu(cap.timeout.a);
- timeout_chip[1] = be32_to_cpu(cap.timeout.b);
- timeout_chip[2] = be32_to_cpu(cap.timeout.c);
- timeout_chip[3] = be32_to_cpu(cap.timeout.d);
- memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff));
-
- /*
- * Provide ability for vendor overrides of timeout values in case
- * of misreporting.
- */
- if (chip->ops->update_timeouts != NULL)
- chip->timeout_adjusted =
- chip->ops->update_timeouts(chip, timeout_eff);
-
- if (!chip->timeout_adjusted) {
- /* Restore default if chip reported 0 */
- int i;
-
- for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) {
- if (timeout_eff[i])
- continue;
-
- timeout_eff[i] = timeout_old[i];
- chip->timeout_adjusted = true;
- }
-
- if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) {
- /* timeouts in msec rather usec */
- for (i = 0; i != ARRAY_SIZE(timeout_eff); i++)
- timeout_eff[i] *= 1000;
- chip->timeout_adjusted = true;
- }
- }
-
- /* Report adjusted timeouts */
- if (chip->timeout_adjusted) {
- dev_info(&chip->dev,
- HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
- timeout_chip[0], timeout_eff[0],
- timeout_chip[1], timeout_eff[1],
- timeout_chip[2], timeout_eff[2],
- timeout_chip[3], timeout_eff[3]);
- }
-
- chip->timeout_a = usecs_to_jiffies(timeout_eff[0]);
- chip->timeout_b = usecs_to_jiffies(timeout_eff[1]);
- chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
- chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);
-
- rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_DURATION, &cap,
- "attempting to determine the durations",
- sizeof(cap.duration));
- if (rc)
- return rc;
-
- chip->duration[TPM_SHORT] =
- usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_short));
- chip->duration[TPM_MEDIUM] =
- usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_medium));
- chip->duration[TPM_LONG] =
- usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_long));
- chip->duration[TPM_LONG_LONG] = 0; /* not used under 1.2 */
-
- /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
- * value wrong and apparently reports msecs rather than usecs. So we
- * fix up the resulting too-small TPM_SHORT value to make things work.
- * We also scale the TPM_MEDIUM and -_LONG values by 1000.
- */
- if (chip->duration[TPM_SHORT] < (HZ / 100)) {
- chip->duration[TPM_SHORT] = HZ;
- chip->duration[TPM_MEDIUM] *= 1000;
- chip->duration[TPM_LONG] *= 1000;
- chip->duration_adjusted = true;
- dev_info(&chip->dev, "Adjusting TPM timeout parameters.");
- }
-
- chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
- return 0;
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ return tpm2_get_timeouts(chip);
+ else
+ return tpm1_get_timeouts(chip);
}
EXPORT_SYMBOL_GPL(tpm_get_timeouts);

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 73511cd89bef..a97d72fcda5b 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -544,8 +544,10 @@ int tpm_startup(struct tpm_chip *chip);
ssize_t tpm_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
const char *desc, size_t min_cap_length);
int tpm_get_timeouts(struct tpm_chip *);
-int tpm1_auto_startup(struct tpm_chip *chip);
int tpm_do_selftest(struct tpm_chip *chip);
+
+int tpm1_auto_startup(struct tpm_chip *chip);
+int tpm1_get_timeouts(struct tpm_chip *chip);
unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
@@ -585,6 +587,7 @@ static inline u32 tpm2_rc_value(u32 rc)
return (rc & BIT(7)) ? rc & 0xff : rc;
}

+int tpm2_get_timeouts(struct tpm_chip *chip);
int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
struct tpm2_digest *digests);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 7e7fa94c095c..cce2f83d90e3 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -307,3 +307,109 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
return duration;
}

+int tpm1_get_timeouts(struct tpm_chip *chip)
+{
+ cap_t cap;
+ unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
+ ssize_t rc;
+
+ rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, NULL,
+ sizeof(cap.timeout));
+ if (rc == TPM_ERR_INVALID_POSTINIT) {
+ if (tpm_startup(chip))
+ return rc;
+
+ rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap,
+ "attempting to determine the timeouts",
+ sizeof(cap.timeout));
+ }
+
+ if (rc) {
+ dev_err(&chip->dev,
+ "A TPM error (%zd) occurred attempting to determine the timeouts\n",
+ rc);
+ return rc;
+ }
+
+ timeout_old[0] = jiffies_to_usecs(chip->timeout_a);
+ timeout_old[1] = jiffies_to_usecs(chip->timeout_b);
+ timeout_old[2] = jiffies_to_usecs(chip->timeout_c);
+ timeout_old[3] = jiffies_to_usecs(chip->timeout_d);
+ timeout_chip[0] = be32_to_cpu(cap.timeout.a);
+ timeout_chip[1] = be32_to_cpu(cap.timeout.b);
+ timeout_chip[2] = be32_to_cpu(cap.timeout.c);
+ timeout_chip[3] = be32_to_cpu(cap.timeout.d);
+ memcpy(timeout_eff, timeout_chip, sizeof(timeout_eff));
+
+ /*
+ * Provide ability for vendor overrides of timeout values in case
+ * of misreporting.
+ */
+ if (chip->ops->update_timeouts)
+ chip->timeout_adjusted =
+ chip->ops->update_timeouts(chip, timeout_eff);
+
+ if (!chip->timeout_adjusted) {
+ /* Restore default if chip reported 0 */
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(timeout_eff); i++) {
+ if (timeout_eff[i])
+ continue;
+
+ timeout_eff[i] = timeout_old[i];
+ chip->timeout_adjusted = true;
+ }
+
+ if (timeout_eff[0] != 0 && timeout_eff[0] < 1000) {
+ /* timeouts in msec rather usec */
+ for (i = 0; i != ARRAY_SIZE(timeout_eff); i++)
+ timeout_eff[i] *= 1000;
+ chip->timeout_adjusted = true;
+ }
+ }
+
+ /* Report adjusted timeouts */
+ if (chip->timeout_adjusted) {
+ dev_info(&chip->dev, HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
+ timeout_chip[0], timeout_eff[0],
+ timeout_chip[1], timeout_eff[1],
+ timeout_chip[2], timeout_eff[2],
+ timeout_chip[3], timeout_eff[3]);
+ }
+
+ chip->timeout_a = usecs_to_jiffies(timeout_eff[0]);
+ chip->timeout_b = usecs_to_jiffies(timeout_eff[1]);
+ chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
+ chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);
+
+ rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_DURATION, &cap,
+ "attempting to determine the durations",
+ sizeof(cap.duration));
+ if (rc)
+ return rc;
+
+ chip->duration[TPM_SHORT] =
+ usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_short));
+ chip->duration[TPM_MEDIUM] =
+ usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_medium));
+ chip->duration[TPM_LONG] =
+ usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_long));
+ chip->duration[TPM_LONG_LONG] = 0; /* not used under 1.2 */
+
+ /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
+ * value wrong and apparently reports msecs rather than usecs. So we
+ * fix up the resulting too-small TPM_SHORT value to make things work.
+ * We also scale the TPM_MEDIUM and -_LONG values by 1000.
+ */
+ if (chip->duration[TPM_SHORT] < (HZ / 100)) {
+ chip->duration[TPM_SHORT] = HZ;
+ chip->duration[TPM_MEDIUM] *= 1000;
+ chip->duration[TPM_LONG] *= 1000;
+ chip->duration_adjusted = true;
+ dev_info(&chip->dev, "Adjusting TPM timeout parameters.");
+ }
+
+ chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
+ return 0;
+}
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index f6c981f3ee12..4ca0555f23c8 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -693,6 +693,28 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
tpm_buf_destroy(&buf);
}

+int tpm2_get_timeouts(struct tpm_chip *chip)
+{
+ /* Fixed timeouts for TPM2 */
+ chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
+ chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
+ chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
+ chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
+
+ /* PTP spec timeouts */
+ chip->duration[TPM_SHORT] = msecs_to_jiffies(TPM2_DURATION_SHORT);
+ chip->duration[TPM_MEDIUM] = msecs_to_jiffies(TPM2_DURATION_MEDIUM);
+ chip->duration[TPM_LONG] = msecs_to_jiffies(TPM2_DURATION_LONG);
+
+ /* Key creation commands long timeouts */
+ chip->duration[TPM_LONG_LONG] =
+ msecs_to_jiffies(TPM2_DURATION_LONG_LONG);
+
+ chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
+
+ return 0;
+}
+
/*
* tpm2_calc_ordinal_duration() - maximum duration for a command
*
--
2.14.4


2018-09-18 09:39:56

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 14/20] tpm: tpm-interface.c drop unused macros

The code movement left some macros unused.

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series

drivers/char/tpm/tpm-interface.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index a8f8e0bcb434..358ef5bd601e 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -33,10 +33,6 @@

#include "tpm.h"

-#define TSC_MAX_ORDINAL 12
-#define TPM_PROTECTED_COMMAND 0x00
-#define TPM_CONNECTION_COMMAND 0x40
-
/*
* Bug workaround - some TPM's don't flush the most
* recently changed pcr on suspend, so force the flush
--
2.14.4


2018-09-18 09:40:04

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 09/20] tpm: move tpm1 selftest code from tpm-interface tpm1-cmd.c

Move the tpm1 selftest code functions to tpm1-cmd.c
and adjust callers to use the new function names.
1. tpm_pcr_read_dev to tpm1_pcr_read_dev
2. tpm_continue_selftest to tpm1_continue_selftest
3. tpm_do_selftest to tpm1_do_selftest

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase

drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
drivers/char/tpm/tpm-interface.c | 148 +----------------------------------
drivers/char/tpm/tpm-sysfs.c | 2 +-
drivers/char/tpm/tpm.h | 4 +-
drivers/char/tpm/tpm1-cmd.c | 142 +++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm_tis_core.c | 2 +-
6 files changed, 150 insertions(+), 150 deletions(-)

diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
index abd675bec88c..64dc560859f2 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -649,7 +649,7 @@ int st33zp24_pm_resume(struct device *dev)
} else {
ret = tpm_pm_resume(dev);
if (!ret)
- tpm_do_selftest(chip);
+ tpm1_do_selftest(chip);
}
return ret;
} /* st33zp24_pm_resume() */
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index c15957fef08f..8396cf6735ec 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -456,59 +456,6 @@ int tpm_get_timeouts(struct tpm_chip *chip)
}
EXPORT_SYMBOL_GPL(tpm_get_timeouts);

-#define TPM_ORD_CONTINUE_SELFTEST 83
-#define CONTINUE_SELFTEST_RESULT_SIZE 10
-
-static const struct tpm_input_header continue_selftest_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(10),
- .ordinal = cpu_to_be32(TPM_ORD_CONTINUE_SELFTEST),
-};
-
-/**
- * tpm_continue_selftest -- run TPM's selftest
- * @chip: TPM chip to use
- *
- * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
- * a TPM error code.
- */
-static int tpm_continue_selftest(struct tpm_chip *chip)
-{
- int rc;
- struct tpm_cmd_t cmd;
-
- cmd.header.in = continue_selftest_header;
- rc = tpm_transmit_cmd(chip, NULL, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
- 0, 0, "continue selftest");
- return rc;
-}
-
-#define TPM_ORDINAL_PCRREAD 21
-#define READ_PCR_RESULT_SIZE 30
-#define READ_PCR_RESULT_BODY_SIZE 20
-static const struct tpm_input_header pcrread_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(14),
- .ordinal = cpu_to_be32(TPM_ORDINAL_PCRREAD)
-};
-
-int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
-{
- int rc;
- struct tpm_cmd_t cmd;
-
- cmd.header.in = pcrread_header;
- cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
- rc = tpm_transmit_cmd(chip, NULL, &cmd, READ_PCR_RESULT_SIZE,
- READ_PCR_RESULT_BODY_SIZE, 0,
- "attempting to read a pcr value");
-
- if (rc == 0)
- memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
- TPM_DIGEST_SIZE);
- return rc;
-}
-
/**
* tpm_is_tpm2 - do we a have a TPM2 chip?
* @chip: a &struct tpm_chip instance, %NULL for the default chip
@@ -549,10 +496,12 @@ int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
chip = tpm_find_get_ops(chip);
if (!chip)
return -ENODEV;
+
if (chip->flags & TPM_CHIP_FLAG_TPM2)
rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
else
- rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
+ rc = tpm1_pcr_read_dev(chip, pcr_idx, res_buf);
+
tpm_put_ops(chip);
return rc;
}
@@ -603,97 +552,6 @@ int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
}
EXPORT_SYMBOL_GPL(tpm_pcr_extend);

-/**
- * tpm_do_selftest - have the TPM continue its selftest and wait until it
- * can receive further commands
- * @chip: TPM chip to use
- *
- * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
- * a TPM error code.
- */
-int tpm_do_selftest(struct tpm_chip *chip)
-{
- int rc;
- unsigned int loops;
- unsigned int delay_msec = 100;
- unsigned long duration;
- u8 dummy[TPM_DIGEST_SIZE];
-
- duration = tpm1_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);
-
- loops = jiffies_to_msecs(duration) / delay_msec;
-
- rc = tpm_continue_selftest(chip);
- if (rc == TPM_ERR_INVALID_POSTINIT) {
- chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
- dev_info(&chip->dev, "TPM not ready (%d)\n", rc);
- }
- /* This may fail if there was no TPM driver during a suspend/resume
- * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
- */
- if (rc)
- return rc;
-
- do {
- /* Attempt to read a PCR value */
- rc = tpm_pcr_read_dev(chip, 0, dummy);
-
- /* Some buggy TPMs will not respond to tpm_tis_ready() for
- * around 300ms while the self test is ongoing, keep trying
- * until the self test duration expires. */
- if (rc == -ETIME) {
- dev_info(
- &chip->dev, HW_ERR
- "TPM command timed out during continue self test");
- tpm_msleep(delay_msec);
- continue;
- }
-
- if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
- dev_info(&chip->dev,
- "TPM is disabled/deactivated (0x%X)\n", rc);
- /* TPM is disabled and/or deactivated; driver can
- * proceed and TPM does handle commands for
- * suspend/resume correctly
- */
- return 0;
- }
- if (rc != TPM_WARN_DOING_SELFTEST)
- return rc;
- tpm_msleep(delay_msec);
- } while (--loops > 0);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_do_selftest);
-
-/**
- * tpm1_auto_startup - Perform the standard automatic TPM initialization
- * sequence
- * @chip: TPM chip to use
- *
- * Returns 0 on success, < 0 in case of fatal error.
- */
-int tpm1_auto_startup(struct tpm_chip *chip)
-{
- int rc;
-
- rc = tpm_get_timeouts(chip);
- if (rc)
- goto out;
- rc = tpm_do_selftest(chip);
- if (rc) {
- dev_err(&chip->dev, "TPM self test failed\n");
- goto out;
- }
-
- return rc;
-out:
- if (rc > 0)
- rc = -ENODEV;
- return rc;
-}
-
/**
* tpm_send - send a TPM command
* @chip: a &struct tpm_chip instance, %NULL for the default chip
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 008515314ae3..861acafd8f29 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -114,7 +114,7 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,

num_pcrs = be32_to_cpu(cap.num_pcrs);
for (i = 0; i < num_pcrs; i++) {
- rc = tpm_pcr_read_dev(chip, i, digest);
+ rc = tpm1_pcr_read_dev(chip, i, digest);
if (rc)
break;
str += sprintf(str, "PCR-%02d: ", i);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 496a56156e77..fd945fc828b6 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -542,13 +542,14 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
const char *desc);
int tpm_startup(struct tpm_chip *chip);
int tpm_get_timeouts(struct tpm_chip *);
-int tpm_do_selftest(struct tpm_chip *chip);

+int tpm1_do_selftest(struct tpm_chip *chip);
int tpm1_auto_startup(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, int pcr_idx, const u8 *hash,
const char *log_msg);
+int tpm1_pcr_read_dev(struct tpm_chip *chip, int 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);
int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max);
@@ -575,7 +576,6 @@ void tpm_chip_unregister(struct tpm_chip *chip);

void tpm_sysfs_add_device(struct tpm_chip *chip);

-int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);

#ifdef CONFIG_ACPI
extern void tpm_add_ppi(struct tpm_chip *chip);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index e7e0528e2e06..3f561736f066 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -525,3 +525,145 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max)

return total ? total : -EIO;
}
+
+#define TPM_ORDINAL_PCRREAD 21
+#define READ_PCR_RESULT_SIZE 30
+#define READ_PCR_RESULT_BODY_SIZE 20
+static const struct tpm_input_header pcrread_header = {
+ .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
+ .length = cpu_to_be32(14),
+ .ordinal = cpu_to_be32(TPM_ORDINAL_PCRREAD)
+};
+
+int tpm1_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+{
+ int rc;
+ struct tpm_cmd_t cmd;
+
+ cmd.header.in = pcrread_header;
+ cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+ rc = tpm_transmit_cmd(chip, NULL, &cmd, READ_PCR_RESULT_SIZE,
+ READ_PCR_RESULT_BODY_SIZE, 0,
+ "attempting to read a pcr value");
+
+ if (rc == 0)
+ memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
+ TPM_DIGEST_SIZE);
+ return rc;
+}
+
+#define TPM_ORD_CONTINUE_SELFTEST 83
+#define CONTINUE_SELFTEST_RESULT_SIZE 10
+static const struct tpm_input_header continue_selftest_header = {
+ .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
+ .length = cpu_to_be32(10),
+ .ordinal = cpu_to_be32(TPM_ORD_CONTINUE_SELFTEST),
+};
+
+/**
+ * tpm_continue_selftest -- run TPM's selftest
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
+ * a TPM error code.
+ */
+static int tpm1_continue_selftest(struct tpm_chip *chip)
+{
+ int rc;
+ struct tpm_cmd_t cmd;
+
+ cmd.header.in = continue_selftest_header;
+ rc = tpm_transmit_cmd(chip, NULL, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
+ 0, 0, "continue selftest");
+ return rc;
+}
+
+/**
+ * tpm1_do_selftest - have the TPM continue its selftest and wait until it
+ * can receive further commands
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
+ * a TPM error code.
+ */
+int tpm1_do_selftest(struct tpm_chip *chip)
+{
+ int rc;
+ unsigned int loops;
+ unsigned int delay_msec = 100;
+ unsigned long duration;
+ u8 dummy[TPM_DIGEST_SIZE];
+
+ duration = tpm1_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);
+
+ loops = jiffies_to_msecs(duration) / delay_msec;
+
+ rc = tpm1_continue_selftest(chip);
+ if (rc == TPM_ERR_INVALID_POSTINIT) {
+ chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
+ dev_info(&chip->dev, "TPM not ready (%d)\n", rc);
+ }
+ /* This may fail if there was no TPM driver during a suspend/resume
+ * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
+ */
+ if (rc)
+ return rc;
+
+ do {
+ /* Attempt to read a PCR value */
+ rc = tpm1_pcr_read_dev(chip, 0, dummy);
+
+ /* Some buggy TPMs will not respond to tpm_tis_ready() for
+ * around 300ms while the self test is ongoing, keep trying
+ * until the self test duration expires.
+ */
+ if (rc == -ETIME) {
+ dev_info(&chip->dev, HW_ERR "TPM command timed out during continue self test");
+ tpm_msleep(delay_msec);
+ continue;
+ }
+
+ if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
+ dev_info(&chip->dev, "TPM is disabled/deactivated (0x%X)\n",
+ rc);
+ /* TPM is disabled and/or deactivated; driver can
+ * proceed and TPM does handle commands for
+ * suspend/resume correctly
+ */
+ return 0;
+ }
+ if (rc != TPM_WARN_DOING_SELFTEST)
+ return rc;
+ tpm_msleep(delay_msec);
+ } while (--loops > 0);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm1_do_selftest);
+
+/**
+ * tpm1_auto_startup - Perform the standard automatic TPM initialization
+ * sequence
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error.
+ */
+int tpm1_auto_startup(struct tpm_chip *chip)
+{
+ int rc;
+
+ rc = tpm1_get_timeouts(chip);
+ if (rc)
+ goto out;
+ rc = tpm1_do_selftest(chip);
+ if (rc) {
+ dev_err(&chip->dev, "TPM self test failed\n");
+ goto out;
+ }
+
+ return rc;
+out:
+ if (rc > 0)
+ rc = -ENODEV;
+ return rc;
+}
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index ced01ec146b5..bf7e49cfa643 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -1056,7 +1056,7 @@ int tpm_tis_resume(struct device *dev)
* an error code but for unknown reason it isn't handled.
*/
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
- tpm_do_selftest(chip);
+ tpm1_do_selftest(chip);

return 0;
}
--
2.14.4


2018-09-18 09:40:05

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 04/20] tpm: add tpm_calc_ordinal_duration wrapper

Add convenient wrapper for ordinal duration computation
to remove boiler plate if else statement over TPM2.

if (chip->flags & TPM_CHIP_FLAG_TPM2)
tpm2_calc_ordinal_duration(chip, ordinal);
else
tpm1_calc_ordinal_duration(chip, ordinal);

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase
drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
drivers/char/tpm/tpm-interface.c | 14 ++++++++++----
drivers/char/tpm/tpm.h | 1 +
drivers/char/tpm/tpm1-cmd.c | 1 -
drivers/char/tpm/tpm2-cmd.c | 1 -
drivers/char/tpm/tpm_i2c_nuvoton.c | 2 +-
drivers/char/tpm/tpm_tis_core.c | 6 +-----
drivers/char/tpm/xen-tpmfront.c | 2 +-
8 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c
index 16be974955ea..abd675bec88c 100644
--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -430,7 +430,7 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));

ret = wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
- tpm1_calc_ordinal_duration(chip, ordinal),
+ tpm_calc_ordinal_duration(chip, ordinal),
&tpm_dev->read_queue, false);
if (ret < 0)
goto out_err;
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index bb3eed907c72..7b460f646781 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -47,6 +47,15 @@ module_param_named(suspend_pcr, tpm_suspend_pcr, uint, 0644);
MODULE_PARM_DESC(suspend_pcr,
"PCR to use for dummy writes to facilitate flush on suspend.");

+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+{
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ return tpm2_calc_ordinal_duration(chip, ordinal);
+ else
+ return tpm1_calc_ordinal_duration(chip, ordinal);
+}
+EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
+
static int tpm_validate_command(struct tpm_chip *chip,
struct tpm_space *space,
const u8 *cmd,
@@ -220,10 +229,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
if (chip->flags & TPM_CHIP_FLAG_IRQ)
goto out_recv;

- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- stop = jiffies + tpm2_calc_ordinal_duration(chip, ordinal);
- else
- stop = jiffies + tpm1_calc_ordinal_duration(chip, ordinal);
+ stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
do {
u8 status = chip->ops->status(chip);
if ((status & chip->ops->req_complete_mask) ==
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index c59d2c20c339..73511cd89bef 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -547,6 +547,7 @@ int tpm_get_timeouts(struct tpm_chip *);
int tpm1_auto_startup(struct tpm_chip *chip);
int tpm_do_selftest(struct tpm_chip *chip);
unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);

diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index fa6ba8d3458c..7e7fa94c095c 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -306,5 +306,4 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
else
return duration;
}
-EXPORT_SYMBOL_GPL(tpm1_calc_ordinal_duration);

diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 9c3c5c0628d9..f6c981f3ee12 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -712,7 +712,6 @@ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
else
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
}
-EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);

/**
* tpm2_do_selftest() - ensure that all self tests have passed
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c
index 5d20e98b844f..4146f822fba9 100644
--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -456,7 +456,7 @@ static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
return rc;
}
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
- duration = tpm1_calc_ordinal_duration(chip, ordinal);
+ duration = tpm_calc_ordinal_duration(chip, ordinal);
rc = i2c_nuvoton_wait_for_data_avail(chip, duration, &priv->read_queue);
if (rc) {
dev_err(dev, "%s() timeout command duration %ld\n",
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index 14c332104de4..f9e73d0f9386 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -473,11 +473,7 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
if (chip->flags & TPM_CHIP_FLAG_IRQ) {
ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));

- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- dur = tpm2_calc_ordinal_duration(chip, ordinal);
- else
- dur = tpm1_calc_ordinal_duration(chip, ordinal);
-
+ dur = tpm_calc_ordinal_duration(chip, ordinal);
if (wait_for_tpm_stat
(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, dur,
&priv->read_queue, false) < 0) {
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
index c7ded298617d..911475d36800 100644
--- a/drivers/char/tpm/xen-tpmfront.c
+++ b/drivers/char/tpm/xen-tpmfront.c
@@ -164,7 +164,7 @@ static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
notify_remote_via_evtchn(priv->evtchn);

ordinal = be32_to_cpu(((struct tpm_input_header*)buf)->ordinal);
- duration = tpm1_calc_ordinal_duration(chip, ordinal);
+ duration = tpm_calc_ordinal_duration(chip, ordinal);

if (wait_for_tpm_stat(chip, VTPM_STATUS_IDLE, duration,
&priv->read_queue, true) < 0) {
--
2.14.4


2018-09-18 09:40:08

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 11/20] tpm: factor out tpm_startup function

tpm manual startup is used only from within tpm1 or tpm2
code, hence remove tpm_startup function from tpm-interface.c
and add two static functions implementations tpm1_startup
and tpm2_startup into to tpm1-cmd.c and tpm2-cmd.c respectively.

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase

drivers/char/tpm/tpm-interface.c | 41 ----------------------------------------
drivers/char/tpm/tpm.h | 1 -
drivers/char/tpm/tpm1-cmd.c | 37 +++++++++++++++++++++++++++++++++++-
drivers/char/tpm/tpm2-cmd.c | 34 +++++++++++++++++++++++++++++++--
4 files changed, 68 insertions(+), 45 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 1ddf9d7e2069..3a2eef9e8665 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -403,47 +403,6 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
}
EXPORT_SYMBOL_GPL(tpm_transmit_cmd);

-#define TPM_ORD_STARTUP 153
-#define TPM_ST_CLEAR 1
-
-/**
- * tpm_startup - turn on the TPM
- * @chip: TPM chip to use
- *
- * Normally the firmware should start the TPM. This function is provided as a
- * workaround if this does not happen. A legal case for this could be for
- * example when a TPM emulator is used.
- *
- * Return: same as tpm_transmit_cmd()
- */
-int tpm_startup(struct tpm_chip *chip)
-{
- struct tpm_buf buf;
- int rc;
-
- dev_info(&chip->dev, "starting up the TPM manually\n");
-
- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP);
- if (rc < 0)
- return rc;
-
- tpm_buf_append_u16(&buf, TPM2_SU_CLEAR);
- } else {
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_STARTUP);
- if (rc < 0)
- return rc;
-
- tpm_buf_append_u16(&buf, TPM_ST_CLEAR);
- }
-
- rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0,
- "attempting to start the TPM");
-
- tpm_buf_destroy(&buf);
- return rc;
-}
-
int tpm_get_timeouts(struct tpm_chip *chip)
{
if (chip->flags & TPM_CHIP_FLAG_HAVE_TIMEOUTS)
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 862c9262e037..fa88102a0cab 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -540,7 +540,6 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
void *buf, size_t bufsiz,
size_t min_rsp_body_length, unsigned int flags,
const char *desc);
-int tpm_startup(struct tpm_chip *chip);
int tpm_get_timeouts(struct tpm_chip *);

int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 5fdc44feea0f..f93776621e49 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -307,6 +307,40 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
return duration;
}

+#define TPM_ORD_STARTUP 153
+#define TPM_ST_CLEAR 1
+
+/**
+ * tpm_startup - turn on the TPM
+ * @chip: TPM chip to use
+ *
+ * Normally the firmware should start the TPM. This function is provided as a
+ * workaround if this does not happen. A legal case for this could be for
+ * example when a TPM emulator is used.
+ *
+ * Return: same as tpm_transmit_cmd()
+ */
+static int tpm1_startup(struct tpm_chip *chip)
+{
+ struct tpm_buf buf;
+ int rc;
+
+ dev_info(&chip->dev, "starting up the TPM manually\n");
+
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_STARTUP);
+ if (rc < 0)
+ return rc;
+
+ tpm_buf_append_u16(&buf, TPM_ST_CLEAR);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0,
+ "attempting to start the TPM");
+
+ tpm_buf_destroy(&buf);
+
+ return rc;
+}
+
int tpm1_get_timeouts(struct tpm_chip *chip)
{
cap_t cap;
@@ -316,7 +350,7 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
rc = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, NULL,
sizeof(cap.timeout));
if (rc == TPM_ERR_INVALID_POSTINIT) {
- if (tpm_startup(chip))
+ if (tpm1_startup(chip))
return rc;

rc = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap,
@@ -721,3 +755,4 @@ int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr)

return rc;
}
+
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 4ca0555f23c8..333631eab4c7 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -943,6 +943,36 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
return rc;
}

+/**
+ * tpm2_startup - turn on the TPM
+ * @chip: TPM chip to use
+ *
+ * Normally the firmware should start the TPM. This function is provided as a
+ * workaround if this does not happen. A legal case for this could be for
+ * example when a TPM emulator is used.
+ *
+ * Return: same as tpm_transmit_cmd()
+ */
+
+static int tpm2_startup(struct tpm_chip *chip)
+{
+ struct tpm_buf buf;
+ int rc;
+
+ dev_info(&chip->dev, "starting up the TPM manually\n");
+
+ rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP);
+ if (rc < 0)
+ return rc;
+
+ tpm_buf_append_u16(&buf, TPM2_SU_CLEAR);
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0,
+ "attempting to start the TPM");
+ tpm_buf_destroy(&buf);
+
+ return rc;
+}
+
/**
* tpm2_auto_startup - Perform the standard automatic TPM initialization
* sequence
@@ -954,7 +984,7 @@ int tpm2_auto_startup(struct tpm_chip *chip)
{
int rc;

- rc = tpm_get_timeouts(chip);
+ rc = tpm2_get_timeouts(chip);
if (rc)
goto out;

@@ -963,7 +993,7 @@ int tpm2_auto_startup(struct tpm_chip *chip)
goto out;

if (rc == TPM2_RC_INITIALIZE) {
- rc = tpm_startup(chip);
+ rc = tpm2_startup(chip);
if (rc)
goto out;

--
2.14.4


2018-09-18 09:40:15

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 13/20] tpm: add tpm_auto_startup into tpm-interface

Add wrapper tpm_auto_startup() to tpm-interface.c
instead of open coded decision between tpm 1.2 and tpm 2.0
in tpm-chip.c

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series

drivers/char/tpm/tpm-chip.c | 11 +++--------
drivers/char/tpm/tpm-interface.c | 15 +++++++++++++++
drivers/char/tpm/tpm.h | 1 +
3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 46caadca916a..32db84683c40 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -451,14 +451,9 @@ int tpm_chip_register(struct tpm_chip *chip)
{
int rc;

- if (chip->ops->flags & TPM_OPS_AUTO_STARTUP) {
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- rc = tpm2_auto_startup(chip);
- else
- rc = tpm1_auto_startup(chip);
- if (rc)
- return rc;
- }
+ rc = tpm_auto_startup(chip);
+ if (rc)
+ return rc;

tpm_sysfs_add_device(chip);

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 54e2cc592bd9..a8f8e0bcb434 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -520,6 +520,21 @@ int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
}
EXPORT_SYMBOL_GPL(tpm_send);

+int tpm_auto_startup(struct tpm_chip *chip)
+{
+ int rc;
+
+ if (!(chip->ops->flags & TPM_OPS_AUTO_STARTUP))
+ return 0;
+
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ rc = tpm2_auto_startup(chip);
+ else
+ rc = tpm1_auto_startup(chip);
+
+ return rc;
+}
+
/*
* We are about to suspend. Save the TPM state
* so that it can be restored.
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index f0963a0a8acd..4ccffbb56864 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -541,6 +541,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
size_t min_rsp_body_length, unsigned int flags,
const char *desc);
int tpm_get_timeouts(struct tpm_chip *);
+int tpm_auto_startup(struct tpm_chip *chip);

int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr);
int tpm1_do_selftest(struct tpm_chip *chip);
--
2.14.4


2018-09-18 09:40:22

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 07/20] tpm: move tpm_getcap to tpm1-cmd.c

1. Move tpm_getcap to tpm1-cmd. Rename the function to tpm1_getcap.
2. Remove unused tpm_getcap_header with unused constant
as this functionality is already implemented using tpm_buf construct.

Fixes warning:
drivers/char/tpm/tpm-interface.c:452:38: warning: ‘tpm_getcap_header’ defined but not used [-Wunused-const-variable=]
static const struct tpm_input_header tpm_getcap_header = {
^~~~~~~~~~~~~~~~~
3. Drop unused TPM_DIGEST_SIZE. It's already defined in
include/linux/tpm.h

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase
drivers/char/tpm/tpm-interface.c | 47 +-----------------------------------
drivers/char/tpm/tpm-sysfs.c | 48 ++++++++++++++++++-------------------
drivers/char/tpm/tpm.h | 4 ++--
drivers/char/tpm/tpm1-cmd.c | 51 +++++++++++++++++++++++++++++++++-------
drivers/char/tpm/tpm_tis_core.c | 2 +-
5 files changed, 71 insertions(+), 81 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 03134f2e1c39..59ca0cdda811 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -444,52 +444,6 @@ int tpm_startup(struct tpm_chip *chip)
return rc;
}

-#define TPM_DIGEST_SIZE 20
-#define TPM_RET_CODE_IDX 6
-#define TPM_INTERNAL_RESULT_SIZE 200
-#define TPM_ORD_GET_CAP 101
-#define TPM_ORD_GET_RANDOM 70
-
-static const struct tpm_input_header tpm_getcap_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(22),
- .ordinal = cpu_to_be32(TPM_ORD_GET_CAP)
-};
-
-ssize_t tpm_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
- const char *desc, size_t min_cap_length)
-{
- struct tpm_buf buf;
- int rc;
-
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_CAP);
- if (rc)
- return rc;
-
- if (subcap_id == TPM_CAP_VERSION_1_1 ||
- subcap_id == TPM_CAP_VERSION_1_2) {
- tpm_buf_append_u32(&buf, subcap_id);
- tpm_buf_append_u32(&buf, 0);
- } else {
- if (subcap_id == TPM_CAP_FLAG_PERM ||
- subcap_id == TPM_CAP_FLAG_VOL)
- tpm_buf_append_u32(&buf, TPM_CAP_FLAG);
- else
- tpm_buf_append_u32(&buf, TPM_CAP_PROP);
-
- tpm_buf_append_u32(&buf, 4);
- tpm_buf_append_u32(&buf, subcap_id);
- }
- rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
- min_cap_length, 0, desc);
- if (!rc)
- *cap = *(cap_t *)&buf.data[TPM_HEADER_SIZE + 4];
-
- tpm_buf_destroy(&buf);
- return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_getcap);
-
int tpm_get_timeouts(struct tpm_chip *chip)
{
if (chip->flags & TPM_CHIP_FLAG_HAVE_TIMEOUTS)
@@ -847,6 +801,7 @@ int tpm_pm_resume(struct device *dev)
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);

+#define TPM_ORD_GET_RANDOM 70
#define TPM_GETRANDOM_RESULT_SIZE 18
static const struct tpm_input_header tpm_getrandom_header = {
.tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 83a77a445538..008515314ae3 100644
--- a/drivers/char/tpm/tpm-sysfs.c
+++ b/drivers/char/tpm/tpm-sysfs.c
@@ -106,9 +106,9 @@ static ssize_t pcrs_show(struct device *dev, struct device_attribute *attr,
char *str = buf;
struct tpm_chip *chip = to_tpm_chip(dev);

- rc = tpm_getcap(chip, TPM_CAP_PROP_PCR, &cap,
- "attempting to determine the number of PCRS",
- sizeof(cap.num_pcrs));
+ rc = tpm1_getcap(chip, TPM_CAP_PROP_PCR, &cap,
+ "attempting to determine the number of PCRS",
+ sizeof(cap.num_pcrs));
if (rc)
return 0;

@@ -132,9 +132,9 @@ static ssize_t enabled_show(struct device *dev, struct device_attribute *attr,
cap_t cap;
ssize_t rc;

- rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
- "attempting to determine the permanent enabled state",
- sizeof(cap.perm_flags));
+ rc = tpm1_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
+ "attempting to determine the permanent enabled state",
+ sizeof(cap.perm_flags));
if (rc)
return 0;

@@ -149,9 +149,9 @@ static ssize_t active_show(struct device *dev, struct device_attribute *attr,
cap_t cap;
ssize_t rc;

- rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
- "attempting to determine the permanent active state",
- sizeof(cap.perm_flags));
+ rc = tpm1_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_PERM, &cap,
+ "attempting to determine the permanent active state",
+ sizeof(cap.perm_flags));
if (rc)
return 0;

@@ -166,9 +166,9 @@ static ssize_t owned_show(struct device *dev, struct device_attribute *attr,
cap_t cap;
ssize_t rc;

- rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
- "attempting to determine the owner state",
- sizeof(cap.owned));
+ rc = tpm1_getcap(to_tpm_chip(dev), TPM_CAP_PROP_OWNER, &cap,
+ "attempting to determine the owner state",
+ sizeof(cap.owned));
if (rc)
return 0;

@@ -183,9 +183,9 @@ static ssize_t temp_deactivated_show(struct device *dev,
cap_t cap;
ssize_t rc;

- rc = tpm_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
- "attempting to determine the temporary state",
- sizeof(cap.stclear_flags));
+ rc = tpm1_getcap(to_tpm_chip(dev), TPM_CAP_FLAG_VOL, &cap,
+ "attempting to determine the temporary state",
+ sizeof(cap.stclear_flags));
if (rc)
return 0;

@@ -202,18 +202,18 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
ssize_t rc;
char *str = buf;

- rc = tpm_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
- "attempting to determine the manufacturer",
- sizeof(cap.manufacturer_id));
+ rc = tpm1_getcap(chip, TPM_CAP_PROP_MANUFACTURER, &cap,
+ "attempting to determine the manufacturer",
+ sizeof(cap.manufacturer_id));
if (rc)
return 0;
str += sprintf(str, "Manufacturer: 0x%x\n",
be32_to_cpu(cap.manufacturer_id));

/* Try to get a TPM version 1.2 TPM_CAP_VERSION_INFO */
- rc = tpm_getcap(chip, TPM_CAP_VERSION_1_2, &cap,
- "attempting to determine the 1.2 version",
- sizeof(cap.tpm_version_1_2));
+ rc = tpm1_getcap(chip, TPM_CAP_VERSION_1_2, &cap,
+ "attempting to determine the 1.2 version",
+ sizeof(cap.tpm_version_1_2));
if (!rc) {
str += sprintf(str,
"TCG version: %d.%d\nFirmware version: %d.%d\n",
@@ -223,9 +223,9 @@ static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
cap.tpm_version_1_2.revMinor);
} else {
/* Otherwise just use TPM_STRUCT_VER */
- rc = tpm_getcap(chip, TPM_CAP_VERSION_1_1, &cap,
- "attempting to determine the 1.1 version",
- sizeof(cap.tpm_version));
+ rc = tpm1_getcap(chip, TPM_CAP_VERSION_1_1, &cap,
+ "attempting to determine the 1.1 version",
+ sizeof(cap.tpm_version));
if (rc)
return 0;
str += sprintf(str,
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 3fb268f43955..1c1980c79c30 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -541,8 +541,6 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
size_t min_rsp_body_length, unsigned int flags,
const char *desc);
int tpm_startup(struct tpm_chip *chip);
-ssize_t tpm_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
- const char *desc, size_t min_cap_length);
int tpm_get_timeouts(struct tpm_chip *);
int tpm_do_selftest(struct tpm_chip *chip);

@@ -551,6 +549,8 @@ 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, int pcr_idx, const u8 *hash,
const char *log_msg);
+ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
+ const char *desc, size_t min_cap_length);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 5c441e1ad8a8..8aa3e3cfed71 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -313,15 +313,15 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
unsigned long timeout_old[4], timeout_chip[4], timeout_eff[4];
ssize_t rc;

- rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, NULL,
- sizeof(cap.timeout));
+ rc = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, NULL,
+ sizeof(cap.timeout));
if (rc == TPM_ERR_INVALID_POSTINIT) {
if (tpm_startup(chip))
return rc;

- rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap,
- "attempting to determine the timeouts",
- sizeof(cap.timeout));
+ rc = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap,
+ "attempting to determine the timeouts",
+ sizeof(cap.timeout));
}

if (rc) {
@@ -383,9 +383,9 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
chip->timeout_c = usecs_to_jiffies(timeout_eff[2]);
chip->timeout_d = usecs_to_jiffies(timeout_eff[3]);

- rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_DURATION, &cap,
- "attempting to determine the durations",
- sizeof(cap.duration));
+ rc = tpm1_getcap(chip, TPM_CAP_PROP_TIS_DURATION, &cap,
+ "attempting to determine the durations",
+ sizeof(cap.duration));
if (rc)
return rc;

@@ -435,3 +435,38 @@ int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,
tpm_buf_destroy(&buf);
return rc;
}
+
+#define TPM_ORD_GET_CAP 101
+ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
+ const char *desc, size_t min_cap_length)
+{
+ struct tpm_buf buf;
+ int rc;
+
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_CAP);
+ if (rc)
+ return rc;
+
+ if (subcap_id == TPM_CAP_VERSION_1_1 ||
+ subcap_id == TPM_CAP_VERSION_1_2) {
+ tpm_buf_append_u32(&buf, subcap_id);
+ tpm_buf_append_u32(&buf, 0);
+ } else {
+ if (subcap_id == TPM_CAP_FLAG_PERM ||
+ subcap_id == TPM_CAP_FLAG_VOL)
+ tpm_buf_append_u32(&buf, TPM_CAP_FLAG);
+ else
+ tpm_buf_append_u32(&buf, TPM_CAP_PROP);
+
+ tpm_buf_append_u32(&buf, 4);
+ tpm_buf_append_u32(&buf, subcap_id);
+ }
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ min_cap_length, 0, desc);
+ if (!rc)
+ *cap = *(cap_t *)&buf.data[TPM_HEADER_SIZE + 4];
+
+ tpm_buf_destroy(&buf);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm1_getcap);
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index f9e73d0f9386..ced01ec146b5 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -664,7 +664,7 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip)
if (chip->flags & TPM_CHIP_FLAG_TPM2)
return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc);
else
- return tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc,
+ return tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc,
0);
}

--
2.14.4


2018-09-18 09:40:33

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 10/20] tpm: factor out tpm1 pm suspend flow into tpm1-cmd.c

Factor out tpm1 suspend flow from tpm-interface.c into a new function
tpm1_pm_suspend in tpm1-cmd.c

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase
drivers/char/tpm/tpm-interface.c | 55 ++++------------------------------------
drivers/char/tpm/tpm.h | 1 +
drivers/char/tpm/tpm1-cmd.c | 54 +++++++++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 8396cf6735ec..1ddf9d7e2069 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -575,15 +575,6 @@ int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
}
EXPORT_SYMBOL_GPL(tpm_send);

-#define TPM_ORD_SAVESTATE 152
-#define SAVESTATE_RESULT_SIZE 10
-
-static const struct tpm_input_header savestate_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(10),
- .ordinal = cpu_to_be32(TPM_ORD_SAVESTATE)
-};
-
/*
* We are about to suspend. Save the TPM state
* so that it can be restored.
@@ -591,54 +582,18 @@ static const struct tpm_input_header savestate_header = {
int tpm_pm_suspend(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
- struct tpm_cmd_t cmd;
- int rc, try;
-
- u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
+ int rc = 0;

- if (chip == NULL)
+ if (!chip)
return -ENODEV;

if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
return 0;

- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
tpm2_shutdown(chip, TPM2_SU_STATE);
- return 0;
- }
-
- /* for buggy tpm, flush pcrs with extend to selected dummy */
- if (tpm_suspend_pcr)
- rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash,
- "extending dummy pcr before suspend");
-
- /* now do the actual savestate */
- for (try = 0; try < TPM_RETRY; try++) {
- cmd.header.in = savestate_header;
- rc = tpm_transmit_cmd(chip, NULL, &cmd, SAVESTATE_RESULT_SIZE,
- 0, 0, NULL);
-
- /*
- * If the TPM indicates that it is too busy to respond to
- * this command then retry before giving up. It can take
- * several seconds for this TPM to be ready.
- *
- * This can happen if the TPM has already been sent the
- * SaveState command before the driver has loaded. TCG 1.2
- * specification states that any communication after SaveState
- * may cause the TPM to invalidate previously saved state.
- */
- if (rc != TPM_WARN_RETRY)
- break;
- tpm_msleep(TPM_TIMEOUT_RETRY);
- }
-
- if (rc)
- dev_err(&chip->dev,
- "Error (%d) sending savestate before suspend\n", rc);
- else if (try > 0)
- dev_warn(&chip->dev, "TPM savestate took %dms\n",
- try * TPM_TIMEOUT_RETRY);
+ else
+ rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);

return rc;
}
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index fd945fc828b6..862c9262e037 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -543,6 +543,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
int tpm_startup(struct tpm_chip *chip);
int tpm_get_timeouts(struct tpm_chip *);

+int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr);
int tpm1_do_selftest(struct tpm_chip *chip);
int tpm1_auto_startup(struct tpm_chip *chip);
int tpm1_get_timeouts(struct tpm_chip *chip);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 3f561736f066..5fdc44feea0f 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -667,3 +667,57 @@ int tpm1_auto_startup(struct tpm_chip *chip)
rc = -ENODEV;
return rc;
}
+
+#define TPM_ORD_SAVESTATE 152
+#define SAVESTATE_RESULT_SIZE 10
+static const struct tpm_input_header savestate_header = {
+ .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
+ .length = cpu_to_be32(10),
+ .ordinal = cpu_to_be32(TPM_ORD_SAVESTATE)
+};
+
+/*
+ * We are about to suspend. Save the TPM state
+ * so that it can be restored.
+ */
+int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr)
+{
+ u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
+ struct tpm_cmd_t cmd;
+ int rc, try;
+
+ /* for buggy tpm, flush pcrs with extend to selected dummy */
+ if (tpm_suspend_pcr)
+ rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash,
+ "extending dummy pcr before suspend");
+
+ /* now do the actual savestate */
+ for (try = 0; try < TPM_RETRY; try++) {
+ cmd.header.in = savestate_header;
+ rc = tpm_transmit_cmd(chip, NULL, &cmd, SAVESTATE_RESULT_SIZE,
+ 0, 0, NULL);
+
+ /*
+ * If the TPM indicates that it is too busy to respond to
+ * this command then retry before giving up. It can take
+ * several seconds for this TPM to be ready.
+ *
+ * This can happen if the TPM has already been sent the
+ * SaveState command before the driver has loaded. TCG 1.2
+ * specification states that any communication after SaveState
+ * may cause the TPM to invalidate previously saved state.
+ */
+ if (rc != TPM_WARN_RETRY)
+ break;
+ tpm_msleep(TPM_TIMEOUT_RETRY);
+ }
+
+ if (rc)
+ dev_err(&chip->dev,
+ "Error (%d) sending savestate before suspend\n", rc);
+ else if (try > 0)
+ dev_warn(&chip->dev, "TPM savestate took %dms\n",
+ try * TPM_TIMEOUT_RETRY);
+
+ return rc;
+}
--
2.14.4


2018-09-18 09:40:33

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 17/20] tpm1: implement tpm1_pcr_read_dev() using tpm_buf structure

Implement tpm1_pcr_read_dev() using tpm_buf and remove
now unneeded structures from tpm.h

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series
drivers/char/tpm/tpm.h | 18 ++----------------
drivers/char/tpm/tpm1-cmd.c | 38 +++++++++++++++++++++-----------------
2 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index d6eca81a011a..d0402aa122ec 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -382,13 +382,10 @@ typedef union {
struct tpm_output_header out;
} tpm_cmd_header;

-struct tpm_pcrread_out {
- u8 pcr_result[TPM_DIGEST_SIZE];
+struct tpm_cmd_t {
+ tpm_cmd_header header;
} __packed;

-struct tpm_pcrread_in {
- __be32 pcr_idx;
-} __packed;

/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
* bytes, but 128 is still a relatively large number of random bytes and
@@ -396,17 +393,6 @@ struct tpm_pcrread_in {
* compiler warnings about stack frame size. */
#define TPM_MAX_RNG_DATA 128

-typedef union {
- struct tpm_pcrread_in pcrread_in;
- struct tpm_pcrread_out pcrread_out;
-} tpm_cmd_params;
-
-struct tpm_cmd_t {
- tpm_cmd_header header;
- tpm_cmd_params params;
-} __packed;
-
-
/* A string buffer type for constructing TPM commands. This is based on the
* ideas of string buffer code in security/keys/trusted.h but is heap based
* in order to keep the stack usage minimal.
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 5708d4bf908f..e81641f9d0e3 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -574,29 +574,33 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
return rc;
}

-#define TPM_ORDINAL_PCRREAD 21
-#define READ_PCR_RESULT_SIZE 30
-#define READ_PCR_RESULT_BODY_SIZE 20
-static const struct tpm_input_header pcrread_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(14),
- .ordinal = cpu_to_be32(TPM_ORDINAL_PCRREAD)
-};
-
+#define TPM_ORD_PCRREAD 21
int tpm1_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
{
+ struct tpm_buf buf;
int rc;
- struct tpm_cmd_t cmd;

- cmd.header.in = pcrread_header;
- cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
- rc = tpm_transmit_cmd(chip, NULL, &cmd, READ_PCR_RESULT_SIZE,
- READ_PCR_RESULT_BODY_SIZE, 0,
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCRREAD);
+ if (rc)
+ return rc;
+
+ tpm_buf_append_u32(&buf, pcr_idx);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ TPM_DIGEST_SIZE, 0,
"attempting to read a pcr value");
+ if (rc)
+ goto out;

- if (rc == 0)
- memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
- TPM_DIGEST_SIZE);
+ if (tpm_buf_length(&buf) < TPM_DIGEST_SIZE) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ memcpy(res_buf, &buf.data[TPM_HEADER_SIZE], TPM_DIGEST_SIZE);
+
+out:
+ tpm_buf_destroy(&buf);
return rc;
}

--
2.14.4


2018-09-18 09:40:38

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 20/20] tpm1: reimplement tpm1_continue_selftest() using tpm_buf

Reimplement tpm1_continue_selftest() using tpm_buf structure.
This is the last command using the old tpm_cmd_t structure
and now the structure can be removed.

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: new in the series
drivers/char/tpm/tpm.h | 9 ---------
drivers/char/tpm/tpm1-cmd.c | 16 ++++++++--------
2 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index dbbfb7118c31..5d018f61b812 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -377,15 +377,6 @@ enum tpm_sub_capabilities {
TPM_CAP_PROP_TIS_DURATION = 0x120,
};

-typedef union {
- struct tpm_input_header in;
- struct tpm_output_header out;
-} tpm_cmd_header;
-
-struct tpm_cmd_t {
- tpm_cmd_header header;
-} __packed;
-

/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
* bytes, but 128 is still a relatively large number of random bytes and
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index c4a0bacb1378..f30d2801c2e0 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -604,11 +604,6 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)

#define TPM_ORD_CONTINUE_SELFTEST 83
#define CONTINUE_SELFTEST_RESULT_SIZE 10
-static const struct tpm_input_header continue_selftest_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(10),
- .ordinal = cpu_to_be32(TPM_ORD_CONTINUE_SELFTEST),
-};

/**
* tpm_continue_selftest -- run TPM's selftest
@@ -619,12 +614,17 @@ static const struct tpm_input_header continue_selftest_header = {
*/
static int tpm1_continue_selftest(struct tpm_chip *chip)
{
+ struct tpm_buf buf;
int rc;
- struct tpm_cmd_t cmd;

- cmd.header.in = continue_selftest_header;
- rc = tpm_transmit_cmd(chip, NULL, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_CONTINUE_SELFTEST);
+ if (rc)
+ return rc;
+ rc = tpm_transmit_cmd(chip, NULL, &buf.data, PAGE_SIZE,
0, 0, "continue selftest");
+
+ tpm_buf_destroy(&buf);
+
return rc;
}

--
2.14.4


2018-09-18 09:40:49

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 06/20] tpm: move tpm1_pcr_extend to tpm1-cmd.c

Move tpm1_pcr_extend to tpm1-cmd.c and remove
unused pcrextend_header structure.

Fixes warning:
drivers/char/tpm/tpm-interface.c:609:38: warning: ‘pcrextend_header’ defined but not used [-Wunused-const-variable=]
static const struct tpm_input_header pcrextend_header = {
^~~~~~~~~~~~~~~~
Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase
drivers/char/tpm/tpm-interface.c | 28 ----------------------------
drivers/char/tpm/tpm.h | 2 ++
drivers/char/tpm/tpm1-cmd.c | 22 ++++++++++++++++++++++
3 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 55f9094a8f11..03134f2e1c39 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -604,34 +604,6 @@ int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
}
EXPORT_SYMBOL_GPL(tpm_pcr_read);

-#define TPM_ORD_PCR_EXTEND 20
-#define EXTEND_PCR_RESULT_SIZE 34
-#define EXTEND_PCR_RESULT_BODY_SIZE 20
-static const struct tpm_input_header pcrextend_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(34),
- .ordinal = cpu_to_be32(TPM_ORD_PCR_EXTEND)
-};
-
-static int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,
- char *log_msg)
-{
- struct tpm_buf buf;
- int rc;
-
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND);
- if (rc)
- return rc;
-
- tpm_buf_append_u32(&buf, pcr_idx);
- tpm_buf_append(&buf, hash, TPM_DIGEST_SIZE);
-
- rc = tpm_transmit_cmd(chip, NULL, buf.data, EXTEND_PCR_RESULT_SIZE,
- EXTEND_PCR_RESULT_BODY_SIZE, 0, log_msg);
- tpm_buf_destroy(&buf);
- return rc;
-}
-
/**
* tpm_pcr_extend - extend a PCR value in SHA1 bank.
* @chip: a &struct tpm_chip instance, %NULL for the default chip
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index a97d72fcda5b..3fb268f43955 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -549,6 +549,8 @@ int tpm_do_selftest(struct tpm_chip *chip);
int tpm1_auto_startup(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, int pcr_idx, const u8 *hash,
+ const char *log_msg);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index cce2f83d90e3..5c441e1ad8a8 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -413,3 +413,25 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
return 0;
}
+
+#define TPM_ORD_PCR_EXTEND 20
+#define EXTEND_PCR_RESULT_SIZE 34
+#define EXTEND_PCR_RESULT_BODY_SIZE 20
+int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,
+ const char *log_msg)
+{
+ struct tpm_buf buf;
+ int rc;
+
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND);
+ if (rc)
+ return rc;
+
+ tpm_buf_append_u32(&buf, pcr_idx);
+ tpm_buf_append(&buf, hash, TPM_DIGEST_SIZE);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, EXTEND_PCR_RESULT_SIZE,
+ EXTEND_PCR_RESULT_BODY_SIZE, 0, log_msg);
+ tpm_buf_destroy(&buf);
+ return rc;
+}
--
2.14.4


2018-09-18 09:41:41

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 12/20] tpm: move pcr extend code to tpm2-cmd.c

Add tpm2_pcr_extend() function to tpm2-cmd.c with signature required
by tpm-interface.c. It wraps the original open code
implementation. The original original tpm2_pcr_extend() function
is renamed and made static, called only from new tpm2_pcr_extend()

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: fix commit message
drivers/char/tpm/tpm-interface.c | 24 +++++-------------------
drivers/char/tpm/tpm.h | 3 +--
drivers/char/tpm/tpm1-cmd.c | 1 +
drivers/char/tpm/tpm2-cmd.c | 24 ++++++++++++++++++++++--
4 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 3a2eef9e8665..54e2cc592bd9 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -481,31 +481,17 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
{
int rc;
- struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)];
- u32 count = 0;
- int i;

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);
- count++;
- }
-
- rc = tpm2_pcr_extend(chip, pcr_idx, count, digest_list);
- tpm_put_ops(chip);
- return rc;
- }
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ rc = tpm2_pcr_extend(chip, pcr_idx, hash);
+ else
+ rc = tpm1_pcr_extend(chip, pcr_idx, hash,
+ "attempting extend a PCR value");

- rc = tpm1_pcr_extend(chip, pcr_idx, hash,
- "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 fa88102a0cab..f0963a0a8acd 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -592,8 +592,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, int pcr_idx, u8 *res_buf);
-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
- struct tpm2_digest *digests);
+int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
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 f93776621e49..90e5bc1720ad 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -466,6 +466,7 @@ int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,

rc = tpm_transmit_cmd(chip, NULL, buf.data, EXTEND_PCR_RESULT_SIZE,
EXTEND_PCR_RESULT_BODY_SIZE, 0, log_msg);
+
tpm_buf_destroy(&buf);
return rc;
}
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 333631eab4c7..b0b714309440 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -178,8 +178,8 @@ struct tpm2_null_auth_area {
*
* Return: Same as with tpm_transmit_cmd.
*/
-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
- struct tpm2_digest *digests)
+static int __tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
+ struct tpm2_digest *digests)
{
struct tpm_buf buf;
struct tpm2_null_auth_area auth_area;
@@ -225,6 +225,26 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
return rc;
}

+int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+{
+ int rc;
+ struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)];
+ u32 count = 0;
+ unsigned int i;
+
+ memset(digest_list, 0, sizeof(digest_list));
+ for (i = 0; i < ARRAY_SIZE(chip->active_banks); i++) {
+ if (chip->active_banks[i] == TPM2_ALG_ERROR)
+ break;
+ digest_list[i].alg_id = chip->active_banks[i];
+ memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE);
+ count++;
+ }
+
+ rc = __tpm2_pcr_extend(chip, pcr_idx, count, digest_list);
+ return rc;
+}
+

struct tpm2_get_random_out {
__be16 size;
--
2.14.4


2018-09-18 09:41:53

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v3 08/20] tpm: factor out tpm1_get_random into tpm1-cmd.c

Factor out get random implementation from tpm-interface.c
into tpm1_get_random function in tpm1-cmd.c.
No functional changes.

Signed-off-by: Tomas Winkler <[email protected]>
---
V2-V3: Rebase

drivers/char/tpm/tpm-interface.c | 58 +++++-----------------------------------
drivers/char/tpm/tpm.h | 1 +
drivers/char/tpm/tpm1-cmd.c | 55 +++++++++++++++++++++++++++++++++++++
3 files changed, 63 insertions(+), 51 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 59ca0cdda811..c15957fef08f 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -801,14 +801,6 @@ int tpm_pm_resume(struct device *dev)
}
EXPORT_SYMBOL_GPL(tpm_pm_resume);

-#define TPM_ORD_GET_RANDOM 70
-#define TPM_GETRANDOM_RESULT_SIZE 18
-static const struct tpm_input_header tpm_getrandom_header = {
- .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
- .length = cpu_to_be32(14),
- .ordinal = cpu_to_be32(TPM_ORD_GET_RANDOM)
-};
-
/**
* tpm_get_random() - get random bytes from the TPM's RNG
* @chip: a &struct tpm_chip instance, %NULL for the default chip
@@ -819,58 +811,22 @@ static const struct tpm_input_header tpm_getrandom_header = {
*/
int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
{
- struct tpm_cmd_t tpm_cmd;
- u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA), rlength;
- int err, total = 0, retries = 5;
- u8 *dest = out;
+ int rc;

- if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
+ if (!out || max > TPM_MAX_RNG_DATA)
return -EINVAL;

chip = tpm_find_get_ops(chip);
if (!chip)
return -ENODEV;

- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
- err = tpm2_get_random(chip, out, max);
- tpm_put_ops(chip);
- return err;
- }
-
- do {
- tpm_cmd.header.in = tpm_getrandom_header;
- tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
-
- err = tpm_transmit_cmd(chip, NULL, &tpm_cmd,
- TPM_GETRANDOM_RESULT_SIZE + num_bytes,
- offsetof(struct tpm_getrandom_out,
- rng_data),
- 0, "attempting get random");
- if (err)
- break;
-
- recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
- if (recd > num_bytes) {
- total = -EFAULT;
- break;
- }
-
- rlength = be32_to_cpu(tpm_cmd.header.out.length);
- if (rlength < TPM_HEADER_SIZE +
- offsetof(struct tpm_getrandom_out, rng_data) +
- recd) {
- total = -EFAULT;
- break;
- }
- memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
-
- dest += recd;
- total += recd;
- num_bytes -= recd;
- } while (retries-- && total < max);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ rc = tpm2_get_random(chip, out, max);
+ else
+ rc = tpm1_get_random(chip, out, max);

tpm_put_ops(chip);
- return total ? total : -EIO;
+ return rc;
}
EXPORT_SYMBOL_GPL(tpm_get_random);

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1c1980c79c30..496a56156e77 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -551,6 +551,7 @@ int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash,
const char *log_msg);
ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
const char *desc, size_t min_cap_length);
+int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max);
unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
int tpm_pm_suspend(struct device *dev);
int tpm_pm_resume(struct device *dev);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 8aa3e3cfed71..e7e0528e2e06 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -470,3 +470,58 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
return rc;
}
EXPORT_SYMBOL_GPL(tpm1_getcap);
+
+#define TPM_ORD_GET_RANDOM 70
+#define TPM_GETRANDOM_RESULT_SIZE 18
+static const struct tpm_input_header tpm_getrandom_header = {
+ .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
+ .length = cpu_to_be32(14),
+ .ordinal = cpu_to_be32(TPM_ORD_GET_RANDOM)
+};
+
+int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max)
+{
+ struct tpm_cmd_t tpm_cmd;
+ u32 recd;
+ u32 num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
+ u32 rlength;
+ int err, total = 0, retries = 5;
+ u8 *dest = out;
+
+ if (!out || !num_bytes || max > TPM_MAX_RNG_DATA)
+ return -EINVAL;
+
+ do {
+ tpm_cmd.header.in = tpm_getrandom_header;
+ tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
+
+ err = tpm_transmit_cmd(chip, NULL, &tpm_cmd,
+ TPM_GETRANDOM_RESULT_SIZE + num_bytes,
+ offsetof(struct tpm_getrandom_out,
+ rng_data),
+ 0, "attempting get random");
+ if (err)
+ break;
+
+ recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len);
+ if (recd > num_bytes) {
+ total = -EFAULT;
+ break;
+ }
+
+ rlength = be32_to_cpu(tpm_cmd.header.out.length);
+ if (rlength < TPM_HEADER_SIZE +
+ offsetof(struct tpm_getrandom_out, rng_data) +
+ recd) {
+ total = -EFAULT;
+ break;
+ }
+ memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
+
+ dest += recd;
+ total += recd;
+ num_bytes -= recd;
+ } while (retries-- && (size_t)total < max);
+
+ return total ? total : -EIO;
+}
--
2.14.4


2018-09-19 14:15:56

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 02/20] tpm: sort objects in the Makefile

On Tue, Sep 18, 2018 at 12:34:41PM +0300, Tomas Winkler wrote:
> Make the tpm Makefile a bit more in order by putting
> objects in one column and group together tpm2 modules

The change is fine but do you mean by the subordinate clause here?

/Jarkko

>
> Signed-off-by: Tomas Winkler <[email protected]>
> ---
> V2: 1. back to tpm-y notation
> 2. Partially sort files alphanumerically.
> V3: Rebase
>
> drivers/char/tpm/Makefile | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
> index 4e9c33ca1f8f..efc785053627 100644
> --- a/drivers/char/tpm/Makefile
> +++ b/drivers/char/tpm/Makefile
> @@ -3,9 +3,18 @@
> # Makefile for the kernel tpm device drivers.
> #
> obj-$(CONFIG_TCG_TPM) += tpm.o
> -tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
> - tpm-dev-common.o tpmrm-dev.o eventlog/common.o eventlog/tpm1.o \
> - eventlog/tpm2.o tpm2-space.o
> +tpm-y := tpm-chip.o
> +tpm-y += tpm-dev-common.o
> +tpm-y += tpm-dev.o
> +tpm-y += tpm-interface.o
> +tpm-y += tpm2-cmd.o
> +tpm-y += tpmrm-dev.o
> +tpm-y += tpm2-space.o
> +tpm-y += tpm-sysfs.o
> +tpm-y += eventlog/common.o
> +tpm-y += eventlog/tpm1.o
> +tpm-y += eventlog/tpm2.o
> +
> tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
> tpm-$(CONFIG_EFI) += eventlog/efi.o
> tpm-$(CONFIG_OF) += eventlog/of.o
> --
> 2.14.4
>

2018-09-19 14:20:04

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 03/20] tpm: factor out tpm 1.x duration calculation to tpm1-cmd.c

On Tue, Sep 18, 2018 at 12:34:42PM +0300, Tomas Winkler wrote:
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2004 IBM Corporation
> + * Copyright (C) 2014 Intel Corporation
> + *
> + * Authors:
> + * Leendert van Doorn <[email protected]>
> + * Dave Safford <[email protected]>
> + * Reiner Sailer <[email protected]>
> + * Kylene Hall <[email protected]>

> + *
> + * Device driver for TCG/TCPA TPM (trusted platform module).
> + * Specifications at http://www.trustedcomputinggroup.org
> + *

This paragraph is not needed. No need to carry it to a new file.

> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation, version 2 of the
> + * License.
> + *
> + */

Cut this out as SPDX takes already care of this.

/Jarkko

2018-09-19 14:20:14

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 01/20] tpm2: add new tpm2 commands according to TCG 1.36

On Wed, Sep 19, 2018 at 04:46:27PM +0300, Jarkko Sakkinen wrote:
> On Tue, Sep 18, 2018 at 12:34:40PM +0300, Tomas Winkler wrote:
> > 1. TPM2_CC_LAST has moved from 182 to 193
> > 2. Convert tpm2_ordinal_duration from an array into a switch statement,
> > as there are not so many commands that require special duration
> > relative to a number of commands.
> >
> > Signed-off-by: Tomas Winkler <[email protected]>
> > ---
> > V2-V3: Rebase.
> > drivers/char/tpm/tpm.h | 41 +++++----
> > drivers/char/tpm/tpm2-cmd.c | 196 +++++++++++++++-----------------------------
> > 2 files changed, 93 insertions(+), 144 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > index f20dc8ece348..0f08518b525d 100644
> > --- a/drivers/char/tpm/tpm.h
> > +++ b/drivers/char/tpm/tpm.h
> > @@ -134,22 +134,31 @@ enum tpm2_algorithms {
> > };
> >
> > enum tpm2_command_codes {
> > - TPM2_CC_FIRST = 0x011F,
> > - TPM2_CC_CREATE_PRIMARY = 0x0131,
> > - TPM2_CC_SELF_TEST = 0x0143,
> > - TPM2_CC_STARTUP = 0x0144,
> > - TPM2_CC_SHUTDOWN = 0x0145,
> > - TPM2_CC_CREATE = 0x0153,
> > - TPM2_CC_LOAD = 0x0157,
> > - TPM2_CC_UNSEAL = 0x015E,
> > - TPM2_CC_CONTEXT_LOAD = 0x0161,
> > - TPM2_CC_CONTEXT_SAVE = 0x0162,
> > - TPM2_CC_FLUSH_CONTEXT = 0x0165,
> > - TPM2_CC_GET_CAPABILITY = 0x017A,
> > - TPM2_CC_GET_RANDOM = 0x017B,
> > - TPM2_CC_PCR_READ = 0x017E,
> > - TPM2_CC_PCR_EXTEND = 0x0182,
> > - TPM2_CC_LAST = 0x018F,
> > + TPM2_CC_FIRST = 0x011F,
> > + TPM2_CC_HIERARCHY_CONTROL = 0x0121,
> > + TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129,
> > + TPM2_CC_CREATE_PRIMARY = 0x0131,
> > + TPM2_CC_SEQUENCE_COMPLETE = 0x013E,
> > + TPM2_CC_SELF_TEST = 0x0143,
> > + TPM2_CC_STARTUP = 0x0144,
> > + TPM2_CC_SHUTDOWN = 0x0145,
> > + TPM2_CC_NV_READ = 0x014E,
> > + TPM2_CC_CREATE = 0x0153,
> > + TPM2_CC_LOAD = 0x0157,
> > + TPM2_CC_SEQUENCE_UPDATE = 0x015C,
> > + TPM2_CC_UNSEAL = 0x015E,
> > + TPM2_CC_CONTEXT_LOAD = 0x0161,
> > + TPM2_CC_CONTEXT_SAVE = 0x0162,
> > + TPM2_CC_FLUSH_CONTEXT = 0x0165,
> > + TPM2_CC_VERIFY_SIGNATURE = 0x0177,
> > + TPM2_CC_GET_CAPABILITY = 0x017A,
> > + TPM2_CC_GET_RANDOM = 0x017B,
> > + TPM2_CC_PCR_READ = 0x017E,
> > + TPM2_CC_PCR_EXTEND = 0x0182,
> > + TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
> > + TPM2_CC_HASH_SEQUENCE_START = 0x0186,
> > + TPM2_CC_CREATE_LOADED = 0x0191,
> > + TPM2_CC_LAST = 0x0193, /* Spec 1.36 */
> > };
> >
> > enum tpm2_permanent_handles {
> > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> > index 3acf4fd4e5a5..9c3c5c0628d9 100644
> > --- a/drivers/char/tpm/tpm2-cmd.c
> > +++ b/drivers/char/tpm/tpm2-cmd.c
> > @@ -41,128 +41,73 @@ static struct tpm2_hash tpm2_hash_map[] = {
> > };
> >
> > /*
> > - * Array with one entry per ordinal defining the maximum amount
> > + * tpm2_ordinal_duration returns the maximum amount
>
> tpm2_ordinal_duration should have parentheses when in a sentence
> for clarity.
>
> Add something this to tpm2_calc_ordinal_duration() instead:
>
> /* tpm2_calc_ordinal_duration - return the maximum amount of time for command duration
> * @ordinal: the command code
> *
> * Return the maximum amount of time for the command duration. The values are
> * taken from the PC Client Profile (PTP) specification. The values can
> * are defined in &enum tpm_duration.
> */
>
> > * of time the chip could take to return the result. The values
> > + * of the MEDIUM, and LONG durations are taken from the
> > + * PC Client Profile (PTP) specification (750, 2000 msec)
> > + *
> > * LONG_LONG is for commands that generates keys which empirically
> > * takes longer time on some systems.
>
> This tail should really be part of the kdoc for enum tpm_duration
> (including the existing comment about LONG_LONG).
>
> > */
> > -static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = {
> > - TPM_UNDEFINED, /* 11F */
> > - TPM_UNDEFINED, /* 120 */
> > - TPM_LONG, /* 121 */
> > - TPM_UNDEFINED, /* 122 */
> > - TPM_UNDEFINED, /* 123 */
> > - TPM_UNDEFINED, /* 124 */
> > - TPM_UNDEFINED, /* 125 */
> > - TPM_UNDEFINED, /* 126 */
> > - TPM_UNDEFINED, /* 127 */
> > - TPM_UNDEFINED, /* 128 */
> > - TPM_LONG, /* 129 */
> > - TPM_UNDEFINED, /* 12a */
> > - TPM_UNDEFINED, /* 12b */
> > - TPM_UNDEFINED, /* 12c */
> > - TPM_UNDEFINED, /* 12d */
> > - TPM_UNDEFINED, /* 12e */
> > - TPM_UNDEFINED, /* 12f */
> > - TPM_UNDEFINED, /* 130 */
> > - TPM_LONG_LONG, /* 131 */
> > - TPM_UNDEFINED, /* 132 */
> > - TPM_UNDEFINED, /* 133 */
> > - TPM_UNDEFINED, /* 134 */
> > - TPM_UNDEFINED, /* 135 */
> > - TPM_UNDEFINED, /* 136 */
> > - TPM_UNDEFINED, /* 137 */
> > - TPM_UNDEFINED, /* 138 */
> > - TPM_UNDEFINED, /* 139 */
> > - TPM_UNDEFINED, /* 13a */
> > - TPM_UNDEFINED, /* 13b */
> > - TPM_UNDEFINED, /* 13c */
> > - TPM_UNDEFINED, /* 13d */
> > - TPM_MEDIUM, /* 13e */
> > - TPM_UNDEFINED, /* 13f */
> > - TPM_UNDEFINED, /* 140 */
> > - TPM_UNDEFINED, /* 141 */
> > - TPM_UNDEFINED, /* 142 */
> > - TPM_LONG, /* 143 */
> > - TPM_MEDIUM, /* 144 */
> > - TPM_UNDEFINED, /* 145 */
> > - TPM_UNDEFINED, /* 146 */
> > - TPM_UNDEFINED, /* 147 */
> > - TPM_UNDEFINED, /* 148 */
> > - TPM_UNDEFINED, /* 149 */
> > - TPM_UNDEFINED, /* 14a */
> > - TPM_UNDEFINED, /* 14b */
> > - TPM_UNDEFINED, /* 14c */
> > - TPM_UNDEFINED, /* 14d */
> > - TPM_LONG, /* 14e */
> > - TPM_UNDEFINED, /* 14f */
> > - TPM_UNDEFINED, /* 150 */
> > - TPM_UNDEFINED, /* 151 */
> > - TPM_UNDEFINED, /* 152 */
> > - TPM_LONG_LONG, /* 153 */
> > - TPM_UNDEFINED, /* 154 */
> > - TPM_UNDEFINED, /* 155 */
> > - TPM_UNDEFINED, /* 156 */
> > - TPM_UNDEFINED, /* 157 */
> > - TPM_UNDEFINED, /* 158 */
> > - TPM_UNDEFINED, /* 159 */
> > - TPM_UNDEFINED, /* 15a */
> > - TPM_UNDEFINED, /* 15b */
> > - TPM_MEDIUM, /* 15c */
> > - TPM_UNDEFINED, /* 15d */
> > - TPM_UNDEFINED, /* 15e */
> > - TPM_UNDEFINED, /* 15f */
> > - TPM_UNDEFINED, /* 160 */
> > - TPM_UNDEFINED, /* 161 */
> > - TPM_UNDEFINED, /* 162 */
> > - TPM_UNDEFINED, /* 163 */
> > - TPM_UNDEFINED, /* 164 */
> > - TPM_UNDEFINED, /* 165 */
> > - TPM_UNDEFINED, /* 166 */
> > - TPM_UNDEFINED, /* 167 */
> > - TPM_UNDEFINED, /* 168 */
> > - TPM_UNDEFINED, /* 169 */
> > - TPM_UNDEFINED, /* 16a */
> > - TPM_UNDEFINED, /* 16b */
> > - TPM_UNDEFINED, /* 16c */
> > - TPM_UNDEFINED, /* 16d */
> > - TPM_UNDEFINED, /* 16e */
> > - TPM_UNDEFINED, /* 16f */
> > - TPM_UNDEFINED, /* 170 */
> > - TPM_UNDEFINED, /* 171 */
> > - TPM_UNDEFINED, /* 172 */
> > - TPM_UNDEFINED, /* 173 */
> > - TPM_UNDEFINED, /* 174 */
> > - TPM_UNDEFINED, /* 175 */
> > - TPM_UNDEFINED, /* 176 */
> > - TPM_LONG, /* 177 */
> > - TPM_UNDEFINED, /* 178 */
> > - TPM_UNDEFINED, /* 179 */
> > - TPM_MEDIUM, /* 17a */
> > - TPM_LONG, /* 17b */
> > - TPM_UNDEFINED, /* 17c */
> > - TPM_UNDEFINED, /* 17d */
> > - TPM_UNDEFINED, /* 17e */
> > - TPM_UNDEFINED, /* 17f */
> > - TPM_UNDEFINED, /* 180 */
> > - TPM_UNDEFINED, /* 181 */
> > - TPM_MEDIUM, /* 182 */
> > - TPM_UNDEFINED, /* 183 */
> > - TPM_UNDEFINED, /* 184 */
> > - TPM_MEDIUM, /* 185 */
> > - TPM_MEDIUM, /* 186 */
> > - TPM_UNDEFINED, /* 187 */
> > - TPM_UNDEFINED, /* 188 */
> > - TPM_UNDEFINED, /* 189 */
> > - TPM_UNDEFINED, /* 18a */
> > - TPM_UNDEFINED, /* 18b */
> > - TPM_UNDEFINED, /* 18c */
> > - TPM_UNDEFINED, /* 18d */
> > - TPM_UNDEFINED, /* 18e */
> > - TPM_UNDEFINED /* 18f */
> > -};
> > +static u8 tpm2_ordinal_duration(u32 ordinal)
>
> This naming scheme becomes confusing. I would suggest to name this
> as __tpm2_calc_ordinal_duration(u32 ordinal).
>
> > +{
> > + switch (ordinal) {
> > + /* Startup */
>
> Please remove these comments. They add only extra weight to maintain
> the code.
>
> > + case TPM2_CC_STARTUP: /* 144 */
> > + return TPM_MEDIUM;
> > +
> > + /* Selftest */
> > + case TPM2_CC_SELF_TEST: /* 143 */
> > + return TPM_LONG;
> > +
> > + /* Random Number Generator */
> > + case TPM2_CC_GET_RANDOM: /* 17B */
> > + return TPM_LONG;
> > +
> > + /* Hash/HMAC/Event Sequences */
> > + case TPM2_CC_SEQUENCE_UPDATE: /* 15C */
> > + return TPM_MEDIUM;
> > + case TPM2_CC_SEQUENCE_COMPLETE: /* 13E */
> > + return TPM_MEDIUM;
> > + case TPM2_CC_EVENT_SEQUENCE_COMPLETE: /* 185 */
> > + return TPM_MEDIUM;
> > + case TPM2_CC_HASH_SEQUENCE_START: /* 186 */
> > + return TPM_MEDIUM;
> > +
> > + /* Signature Verification */
> > + case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
> > + return TPM_LONG;
> > +
> > + /* Integrity Collection (PCR) */
> > + case TPM2_CC_PCR_EXTEND: /* 182 */
> > + return TPM_MEDIUM;
> > +
> > + /* Hierarchy Commands */
> > + case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
> > + return TPM_LONG;
> > + case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
> > + return TPM_LONG;
> > +
> > + /* Capability Commands */
> > + case TPM2_CC_GET_CAPABILITY: /* 17A */
> > + return TPM_MEDIUM;
> > +
> > + /* Non-volatile Storage */
> > + case TPM2_CC_NV_READ: /* 14E */
> > + return TPM_LONG;
> > +
> > + /* Key generation (not in PTP) */
> > + case TPM2_CC_CREATE_PRIMARY: /* 131 */
> > + return TPM_LONG_LONG;
> > + case TPM2_CC_CREATE: /* 153 */
> > + return TPM_LONG_LONG;
> > + case TPM2_CC_CREATE_LOADED: /* 191 */
> > + return TPM_LONG_LONG;
> > +
> > + default:
> > + return TPM_UNDEFINED;
> > + }
> > +}
> >
> > struct tpm2_pcr_read_out {
> > __be32 update_cnt;
> > @@ -758,19 +703,14 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
> > */
> > unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
> > {
> > - int index = TPM_UNDEFINED;
> > - int duration = 0;
> > + unsigned int index;
> >
> > - if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST)
> > - index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST];
> > + index = tpm2_ordinal_duration(ordinal);
> >
> > if (index != TPM_UNDEFINED)
> > - duration = chip->duration[index];
> > -
> > - if (duration <= 0)
> > - duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT);
> > -
> > - return duration;
> > + return chip->duration[index];
> > + else
> > + return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
> > }
> > EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
> >
> > --
> > 2.14.4
> >
>
> /Jarkko

Forgot to add this:

Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 14:20:21

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 02/20] tpm: sort objects in the Makefile

On Wed, Sep 19, 2018 at 04:48:53PM +0300, Jarkko Sakkinen wrote:
> On Tue, Sep 18, 2018 at 12:34:41PM +0300, Tomas Winkler wrote:
> > Make the tpm Makefile a bit more in order by putting
> > objects in one column and group together tpm2 modules
>
> The change is fine but do you mean by the subordinate clause here?
>
> /Jarkko
>
> >
> > Signed-off-by: Tomas Winkler <[email protected]>
> > ---
> > V2: 1. back to tpm-y notation
> > 2. Partially sort files alphanumerically.
> > V3: Rebase
> >
> > drivers/char/tpm/Makefile | 15 ++++++++++++---
> > 1 file changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
> > index 4e9c33ca1f8f..efc785053627 100644
> > --- a/drivers/char/tpm/Makefile
> > +++ b/drivers/char/tpm/Makefile
> > @@ -3,9 +3,18 @@
> > # Makefile for the kernel tpm device drivers.
> > #
> > obj-$(CONFIG_TCG_TPM) += tpm.o
> > -tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
> > - tpm-dev-common.o tpmrm-dev.o eventlog/common.o eventlog/tpm1.o \
> > - eventlog/tpm2.o tpm2-space.o
> > +tpm-y := tpm-chip.o
> > +tpm-y += tpm-dev-common.o
> > +tpm-y += tpm-dev.o
> > +tpm-y += tpm-interface.o
> > +tpm-y += tpm2-cmd.o
> > +tpm-y += tpmrm-dev.o
> > +tpm-y += tpm2-space.o
> > +tpm-y += tpm-sysfs.o
> > +tpm-y += eventlog/common.o
> > +tpm-y += eventlog/tpm1.o
> > +tpm-y += eventlog/tpm2.o
> > +
> > tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
> > tpm-$(CONFIG_EFI) += eventlog/efi.o
> > tpm-$(CONFIG_OF) += eventlog/of.o
> > --
> > 2.14.4
> >

Forgot to add this:

Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 14:20:29

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 03/20] tpm: factor out tpm 1.x duration calculation to tpm1-cmd.c

On Wed, Sep 19, 2018 at 04:55:17PM +0300, Jarkko Sakkinen wrote:
> On Tue, Sep 18, 2018 at 12:34:42PM +0300, Tomas Winkler wrote:
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2004 IBM Corporation
> > + * Copyright (C) 2014 Intel Corporation
> > + *
> > + * Authors:
> > + * Leendert van Doorn <[email protected]>
> > + * Dave Safford <[email protected]>
> > + * Reiner Sailer <[email protected]>
> > + * Kylene Hall <[email protected]>
>
> > + *
> > + * Device driver for TCG/TCPA TPM (trusted platform module).
> > + * Specifications at http://www.trustedcomputinggroup.org
> > + *
>
> This paragraph is not needed. No need to carry it to a new file.
>
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License as
> > + * published by the Free Software Foundation, version 2 of the
> > + * License.
> > + *
> > + */
>
> Cut this out as SPDX takes already care of this.
>
> /Jarkko

Forgot to add this:

Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 14:20:58

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 05/20] tpm: factor out tpm_get_timeouts

On Tue, Sep 18, 2018 at 12:34:44PM +0300, Tomas Winkler wrote:
> Factor out tpm_get_timeouts into tpm2_get_timeouts
> and tpm1_get_timeouts.

Function names missing parentheses. Should be there for clarity when
used in a sentence. Otherwise, the commit looks fine.

Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 14:21:31

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 04/20] tpm: add tpm_calc_ordinal_duration wrapper

On Tue, Sep 18, 2018 at 12:34:43PM +0300, Tomas Winkler wrote:
> Add convenient wrapper for ordinal duration computation
> to remove boiler plate if else statement over TPM2.
>
> if (chip->flags & TPM_CHIP_FLAG_TPM2)
> tpm2_calc_ordinal_duration(chip, ordinal);
> else
> tpm1_calc_ordinal_duration(chip, ordinal);
>
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 14:21:32

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 07/20] tpm: move tpm_getcap to tpm1-cmd.c

On Tue, Sep 18, 2018 at 12:34:46PM +0300, Tomas Winkler wrote:
> 1. Move tpm_getcap to tpm1-cmd. Rename the function to tpm1_getcap.
> 2. Remove unused tpm_getcap_header with unused constant
> as this functionality is already implemented using tpm_buf construct.
>
> Fixes warning:
> drivers/char/tpm/tpm-interface.c:452:38: warning: ‘tpm_getcap_header’ defined but not used [-Wunused-const-variable=]
> static const struct tpm_input_header tpm_getcap_header = {
> ^~~~~~~~~~~~~~~~~
> 3. Drop unused TPM_DIGEST_SIZE. It's already defined in
> include/linux/tpm.h

Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 14:22:01

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 06/20] tpm: move tpm1_pcr_extend to tpm1-cmd.c

On Tue, Sep 18, 2018 at 12:34:45PM +0300, Tomas Winkler wrote:
> Move tpm1_pcr_extend to tpm1-cmd.c and remove
> unused pcrextend_header structure.
>
> Fixes warning:
> drivers/char/tpm/tpm-interface.c:609:38: warning: ‘pcrextend_header’ defined but not used [-Wunused-const-variable=]
> static const struct tpm_input_header pcrextend_header = {
> ^~~~~~~~~~~~~~~~
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkinen <[email protected]>

Can someone with a working IMA environment to test it? Don't have one
right now (should probably setup).

/Jarkko

2018-09-19 14:57:51

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 08/20] tpm: factor out tpm1_get_random into tpm1-cmd.c

On Tue, Sep 18, 2018 at 12:34:47PM +0300, Tomas Winkler wrote:
> Factor out get random implementation from tpm-interface.c
> into tpm1_get_random function in tpm1-cmd.c.
> No functional changes.
>
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkine <[email protected]>

/Jarkko

2018-09-19 15:00:00

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 12/20] tpm: move pcr extend code to tpm2-cmd.c

On Tue, Sep 18, 2018 at 12:34:51PM +0300, Tomas Winkler wrote:
> Add tpm2_pcr_extend() function to tpm2-cmd.c with signature required
> by tpm-interface.c. It wraps the original open code
> implementation. The original original tpm2_pcr_extend() function
> is renamed and made static, called only from new tpm2_pcr_extend()
>
> Signed-off-by: Tomas Winkler <[email protected]>

The change is OK. The last sentence in the commit message needs to
be fixed.


/Jarkko

2018-09-19 15:04:12

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 10/20] tpm: factor out tpm1 pm suspend flow into tpm1-cmd.c

On Tue, Sep 18, 2018 at 12:34:49PM +0300, Tomas Winkler wrote:
> Factor out tpm1 suspend flow from tpm-interface.c into a new function
> tpm1_pm_suspend in tpm1-cmd.c
>
> Signed-off-by: Tomas Winkler <[email protected]>

Use "TPM 1.x" in the short summary and long description instead of
"tpm1" and add parentheses to the functions.

> ---
> V2-V3: Rebase
> drivers/char/tpm/tpm-interface.c | 55 ++++------------------------------------
> drivers/char/tpm/tpm.h | 1 +
> drivers/char/tpm/tpm1-cmd.c | 54 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 60 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index 8396cf6735ec..1ddf9d7e2069 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -575,15 +575,6 @@ int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
> }
> EXPORT_SYMBOL_GPL(tpm_send);
>
> -#define TPM_ORD_SAVESTATE 152
> -#define SAVESTATE_RESULT_SIZE 10
> -
> -static const struct tpm_input_header savestate_header = {
> - .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
> - .length = cpu_to_be32(10),
> - .ordinal = cpu_to_be32(TPM_ORD_SAVESTATE)
> -};
> -
> /*
> * We are about to suspend. Save the TPM state
> * so that it can be restored.
> @@ -591,54 +582,18 @@ static const struct tpm_input_header savestate_header = {
> int tpm_pm_suspend(struct device *dev)
> {
> struct tpm_chip *chip = dev_get_drvdata(dev);
> - struct tpm_cmd_t cmd;
> - int rc, try;
> -
> - u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
> + int rc = 0;
>
> - if (chip == NULL)
> + if (!chip)
> return -ENODEV;
>
> if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
> return 0;
>
> - if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> + if (chip->flags & TPM_CHIP_FLAG_TPM2)
> tpm2_shutdown(chip, TPM2_SU_STATE);
> - return 0;
> - }
> -
> - /* for buggy tpm, flush pcrs with extend to selected dummy */
> - if (tpm_suspend_pcr)
> - rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash,
> - "extending dummy pcr before suspend");
> -
> - /* now do the actual savestate */
> - for (try = 0; try < TPM_RETRY; try++) {
> - cmd.header.in = savestate_header;
> - rc = tpm_transmit_cmd(chip, NULL, &cmd, SAVESTATE_RESULT_SIZE,
> - 0, 0, NULL);
> -
> - /*
> - * If the TPM indicates that it is too busy to respond to
> - * this command then retry before giving up. It can take
> - * several seconds for this TPM to be ready.
> - *
> - * This can happen if the TPM has already been sent the
> - * SaveState command before the driver has loaded. TCG 1.2
> - * specification states that any communication after SaveState
> - * may cause the TPM to invalidate previously saved state.
> - */
> - if (rc != TPM_WARN_RETRY)
> - break;
> - tpm_msleep(TPM_TIMEOUT_RETRY);
> - }
> -
> - if (rc)
> - dev_err(&chip->dev,
> - "Error (%d) sending savestate before suspend\n", rc);
> - else if (try > 0)
> - dev_warn(&chip->dev, "TPM savestate took %dms\n",
> - try * TPM_TIMEOUT_RETRY);
> + else
> + rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
>
> return rc;
> }
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index fd945fc828b6..862c9262e037 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -543,6 +543,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space,
> int tpm_startup(struct tpm_chip *chip);
> int tpm_get_timeouts(struct tpm_chip *);
>
> +int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr);
> int tpm1_do_selftest(struct tpm_chip *chip);
> int tpm1_auto_startup(struct tpm_chip *chip);
> int tpm1_get_timeouts(struct tpm_chip *chip);
> diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
> index 3f561736f066..5fdc44feea0f 100644
> --- a/drivers/char/tpm/tpm1-cmd.c
> +++ b/drivers/char/tpm/tpm1-cmd.c
> @@ -667,3 +667,57 @@ int tpm1_auto_startup(struct tpm_chip *chip)
> rc = -ENODEV;
> return rc;
> }
> +
> +#define TPM_ORD_SAVESTATE 152
> +#define SAVESTATE_RESULT_SIZE 10
> +static const struct tpm_input_header savestate_header = {
> + .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND),
> + .length = cpu_to_be32(10),
> + .ordinal = cpu_to_be32(TPM_ORD_SAVESTATE)
> +};
> +
> +/*
> + * We are about to suspend. Save the TPM state
> + * so that it can be restored.
> + */

Either remove this comment or do a proper kdoc.

> +int tpm1_pm_suspend(struct tpm_chip *chip, int tpm_suspend_pcr)
> +{
> + u8 dummy_hash[TPM_DIGEST_SIZE] = { 0 };
> + struct tpm_cmd_t cmd;
> + int rc, try;
> +
> + /* for buggy tpm, flush pcrs with extend to selected dummy */
> + if (tpm_suspend_pcr)
> + rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash,
> + "extending dummy pcr before suspend");
> +
> + /* now do the actual savestate */
> + for (try = 0; try < TPM_RETRY; try++) {
> + cmd.header.in = savestate_header;
> + rc = tpm_transmit_cmd(chip, NULL, &cmd, SAVESTATE_RESULT_SIZE,
> + 0, 0, NULL);
> +
> + /*
> + * If the TPM indicates that it is too busy to respond to
> + * this command then retry before giving up. It can take
> + * several seconds for this TPM to be ready.
> + *
> + * This can happen if the TPM has already been sent the
> + * SaveState command before the driver has loaded. TCG 1.2
> + * specification states that any communication after SaveState
> + * may cause the TPM to invalidate previously saved state.
> + */
> + if (rc != TPM_WARN_RETRY)
> + break;
> + tpm_msleep(TPM_TIMEOUT_RETRY);
> + }
> +
> + if (rc)
> + dev_err(&chip->dev,
> + "Error (%d) sending savestate before suspend\n", rc);
> + else if (try > 0)
> + dev_warn(&chip->dev, "TPM savestate took %dms\n",
> + try * TPM_TIMEOUT_RETRY);
> +
> + return rc;
> +}
> --
> 2.14.4
>

/Jarkko

2018-09-19 15:06:44

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 09/20] tpm: move tpm1 selftest code from tpm-interface tpm1-cmd.c

On Tue, Sep 18, 2018 at 12:34:48PM +0300, Tomas Winkler wrote:
> Move the tpm1 selftest code functions to tpm1-cmd.c

TPM 1.x. Also, the function names are missing parentheses.

Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 15:08:20

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 11/20] tpm: factor out tpm_startup function

On Tue, Sep 18, 2018 at 12:34:50PM +0300, Tomas Winkler wrote:
> tpm manual startup is used only from within tpm1 or tpm2
> code, hence remove tpm_startup function from tpm-interface.c
> and add two static functions implementations tpm1_startup
> and tpm2_startup into to tpm1-cmd.c and tpm2-cmd.c respectively.
>
> Signed-off-by: Tomas Winkler <[email protected]>

Again, language in the commit message. For example, I guess usually
we write abbrevation "TPM" and not "tpm".

Tested-by: Jarkko Sakkine <[email protected]>

/Jarkko

2018-09-19 15:10:07

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 13/20] tpm: add tpm_auto_startup into tpm-interface

On Tue, Sep 18, 2018 at 12:34:52PM +0300, Tomas Winkler wrote:
> Add wrapper tpm_auto_startup() to tpm-interface.c
> instead of open coded decision between tpm 1.2 and tpm 2.0
> in tpm-chip.c
>
> Signed-off-by: Tomas Winkler <[email protected]>

Language.

> ---
> V3: new in the series

Please put the changelog to the cover letter only.

Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 15:12:51

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 14/20] tpm: tpm-interface.c drop unused macros

On Tue, Sep 18, 2018 at 12:34:53PM +0300, Tomas Winkler wrote:
> The code movement left some macros unused.

Rewrite the long description and the language is horrible. The code
movement maps to nothing. Should be something along the lines: "The
migration of the TPM 1.x code has left some unused macros to
tpm-interface.c. Remove those macros."

/Jarkko

>
> Signed-off-by: Tomas Winkler <[email protected]>
> ---
> V3: new in the series
>
> drivers/char/tpm/tpm-interface.c | 4 ----
> 1 file changed, 4 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index a8f8e0bcb434..358ef5bd601e 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -33,10 +33,6 @@
>
> #include "tpm.h"
>
> -#define TSC_MAX_ORDINAL 12
> -#define TPM_PROTECTED_COMMAND 0x00
> -#define TPM_CONNECTION_COMMAND 0x40
> -
> /*
> * Bug workaround - some TPM's don't flush the most
> * recently changed pcr on suspend, so force the flush
> --
> 2.14.4
>

2018-09-19 15:13:12

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 15/20] tpm: tpm-space.c remove unneeded semicolon

On Tue, Sep 18, 2018 at 12:34:54PM +0300, Tomas Winkler wrote:
> Remove unneeded semicolon in tpm2_map_response_header()
>
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 15:14:05

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 16/20] tpm: tpm1: rewrite tpm1_get_random() using tpm_buf structure

On Tue, Sep 18, 2018 at 12:34:55PM +0300, Tomas Winkler wrote:
> 1. Use tpm_buf in tpm1_get_random()
> 2. Fix comment in tpm_get_random() so it is clear that
> the function is expected to return number of random bytes.
>
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 15:14:39

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 17/20] tpm1: implement tpm1_pcr_read_dev() using tpm_buf structure

On Tue, Sep 18, 2018 at 12:34:56PM +0300, Tomas Winkler wrote:
> Implement tpm1_pcr_read_dev() using tpm_buf and remove
> now unneeded structures from tpm.h
>
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-19 15:23:11

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 18/20] tpm: use u32 instead of int for pcr index

On Tue, Sep 18, 2018 at 12:34:57PM +0300, Tomas Winkler wrote:
> TPM pcr indices cannot be negative, also the tpm
> commands accept u32 number as a pcr index.
>
> 1. Adjust the API to use u32 instead of int in all pcr related
> functions.

NAK.

> 2. Rename tpm1_pcr_read_dev to tpm1_pcr_read() to match
> the counterpart tpm2_pcr_read()

I would accept this a separate commit (and it should be a separate).

> 3. Remove redundant constants in tpm1_pcr_extend() function.
>
> Signed-off-by: Tomas Winkler <[email protected]>

/Jarkko

2018-09-19 15:25:08

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 20/20] tpm1: reimplement tpm1_continue_selftest() using tpm_buf

On Tue, Sep 18, 2018 at 12:34:59PM +0300, Tomas Winkler wrote:
> Reimplement tpm1_continue_selftest() using tpm_buf structure.
> This is the last command using the old tpm_cmd_t structure
> and now the structure can be removed.
>
> Signed-off-by: Tomas Winkler <[email protected]>

Minor rant: the last sentence should state simply that as there
are no other fields in tpm_cmd_t can be removed. The rationale
is that the patch set ceases to exist after it is accepted. It
is a temporary item, not something that should be referred in
the commit log.

/Jarkko

2018-09-19 15:25:10

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v3 19/20] tpm1: reimplement SAVESTATE using tpm_buf

On Tue, Sep 18, 2018 at 12:34:58PM +0300, Tomas Winkler wrote:
> In tpm1_pm_suspend() function reimplement,
> TPM_ORD_SAVESTATE comamnd using tpm_buf.
>
> Signed-off-by: Tomas Winkler <[email protected]>

Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>

/Jarkko

2018-09-25 16:29:01

by Nayna Jain

[permalink] [raw]
Subject: Re: [PATCH v3 06/20] tpm: move tpm1_pcr_extend to tpm1-cmd.c



On 09/19/2018 07:36 PM, Jarkko Sakkinen wrote:
> On Tue, Sep 18, 2018 at 12:34:45PM +0300, Tomas Winkler wrote:
>> Move tpm1_pcr_extend to tpm1-cmd.c and remove
>> unused pcrextend_header structure.
>>
>> Fixes warning:
>> drivers/char/tpm/tpm-interface.c:609:38: warning: ‘pcrextend_header’ defined but not used [-Wunused-const-variable=]
>> static const struct tpm_input_header pcrextend_header = {
>> ^~~~~~~~~~~~~~~~
>> Signed-off-by: Tomas Winkler <[email protected]>
> Reviewed-by: Jarkko Sakkinen <[email protected]>
>
> Can someone with a working IMA environment to test it? Don't have one
> right now (should probably setup).

I think I can try testing this patch sometime next week. I will test the
updated version.

Thanks & Regards,
    - Nayna

>
> /Jarkko
>