2018-09-28 22:35:13

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 00/21] 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 (21):
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 tpm 1.x selftest code from tpm-interface.c tpm1-cmd.c
tpm: factor out tpm 1.x 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.c
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
tmp1: rename tpm1_pcr_read_dev to tpm1_pcr_read().
tpm1: reimplement SAVESTATE using tpm_buf
tpm1: reimplement tpm1_continue_selftest() using tpm_buf
tpm: use u32 instead of int for PCR index

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 | 841 +++--------------------------------
drivers/char/tpm/tpm-sysfs.c | 52 +--
drivers/char/tpm/tpm.h | 98 ++--
drivers/char/tpm/tpm1-cmd.c | 781 ++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm2-cmd.c | 344 +++++++-------
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 | 11 +-
security/integrity/ima/ima_crypto.c | 5 +-
13 files changed, 1121 insertions(+), 1062 deletions(-)
create mode 100644 drivers/char/tpm/tpm1-cmd.c

--
2.14.4



2018-09-28 22:36:07

by Tomas Winkler

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

Remove unneeded semicolon in tpm2_map_response_header()

Signed-off-by: Tomas Winkler <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
---

V3: New in the series.
V4-V5: Resend.

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-28 22:36:09

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 17/21] 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]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---

V3: New in the series.
V4-V5: Resend.
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 b5c4fa158c30..d30f336518f6 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -571,29 +571,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-28 22:36:12

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 19/21] 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]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V3: New in the series.
V4-V5: Resend

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 05b772477bac..d418a27a75e0 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -718,12 +718,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)
-};

/**
* tpm1_pm_suspend() - pm suspend handler
@@ -739,18 +733,22 @@ static const struct tpm_input_header savestate_header = {
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;
+ 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);

/*
@@ -766,6 +764,8 @@ int tpm1_pm_suspend(struct tpm_chip *chip, int 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)
@@ -775,6 +775,8 @@ int tpm1_pm_suspend(struct tpm_chip *chip, int 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-28 22:36:17

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 21/21] tpm: use u32 instead of int for PCR index

The TPM specs defines PCR index as a positive number, and there is
no reason to use a signed number. It is also a possible security
issue as currently no functions check for a negative index,
which may become a large number when converted to u32.

Adjust the API to use u32 instead of int in all PCR related
functions.

Signed-off-by: Tomas Winkler <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
---
V3: New in the series.
V4: Separate unrelated change to another patches.
V5: Fix the commit message.

drivers/char/tpm/tpm-interface.c | 6 +++---
drivers/char/tpm/tpm-sysfs.c | 2 +-
drivers/char/tpm/tpm.h | 10 +++++-----
drivers/char/tpm/tpm1-cmd.c | 6 +++---
drivers/char/tpm/tpm2-cmd.c | 6 +++---
include/linux/tpm.h | 11 +++++++----
security/integrity/ima/ima_crypto.c | 5 +++--
7 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 3d80c5114fec..c27106b4a35e 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -38,7 +38,7 @@
* recently changed pcr on suspend, so force the flush
* with an extend to the selected _unused_ non-volatile pcr.
*/
-static int tpm_suspend_pcr;
+static u32 tpm_suspend_pcr;
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.");
@@ -454,7 +454,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;

@@ -484,7 +484,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
*
* Return: same as with tpm_transmit_cmd()
*/
-int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash)
{
int rc;

diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
index 96fc7433c57d..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);

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 7ada00f067f1..5d018f61b812 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -509,14 +509,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(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);
@@ -558,8 +558,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 6b04648f8184..6f306338953b 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -449,7 +449,7 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
}

#define TPM_ORD_PCR_EXTEND 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;
@@ -572,7 +572,7 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
}

#define TPM_ORD_PCRREAD 21
-int tpm1_pcr_read(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;
@@ -729,7 +729,7 @@ int tpm1_auto_startup(struct tpm_chip *chip)
* * 0 on success,
* * < 0 on error.
*/
-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_buf buf;
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 2b705b00db78..c2667d3e9dae 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -175,7 +175,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;
@@ -224,7 +224,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;
@@ -278,7 +278,7 @@ static int __tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
*
* Return: Same as with tpm_transmit_cmd.
*/
-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..b49a55cf775f 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -53,8 +53,8 @@ struct tpm_class_ops {
#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)

extern int tpm_is_tpm2(struct tpm_chip *chip);
-extern int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
-extern int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
+extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
+extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash);
extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen);
extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max);
extern int tpm_seal_trusted(struct tpm_chip *chip,
@@ -69,15 +69,18 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
{
return -ENODEV;
}
-static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+
+static inline int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
{
return -ENODEV;
}
-static inline int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx,
+
+static inline int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
const u8 *hash)
{
return -ENODEV;
}
+
static inline int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
{
return -ENODEV;
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-28 22:36:27

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 02/21] tpm: sort objects in the Makefile

Make the tpm Makefile a bit more in order by putting
objects in one column.

Signed-off-by: Tomas Winkler <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
---
V2: 1. back to tpm-y notation
2. Partially sort files alphanumerically.
V3: Rebase
V4: Remove redunant sentence in commit message.
V5: Resend

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-28 22:36:30

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 16/21] 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]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V3: New in the series.
V4: Resend.
V5: A small adjustment in the kdoc.

drivers/char/tpm/tpm-interface.c | 2 +-
drivers/char/tpm/tpm.h | 11 ------
drivers/char/tpm/tpm1-cmd.c | 84 +++++++++++++++++++++++-----------------
3 files changed, 49 insertions(+), 48 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 98f9a0bbeed9..0af71d53d129 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -586,7 +586,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 8a84db315676..b5c4fa158c30 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -505,58 +505,70 @@ 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 ? (int)total : -EIO;
+out:
+ tpm_buf_destroy(&buf);
+ return rc;
}

#define TPM_ORDINAL_PCRREAD 21
--
2.14.4


2018-09-28 22:36:42

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 01/21] 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, the switch statement function
is called tpm2_ordinal_duration_index().
3. Fix kdoc comments for tpm2_calc_ordinal_duration().

Signed-off-by: Tomas Winkler <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---

V2-V3: Rebase.
V4: 1. Fix kdoc
2. Rename tpm2_ordinal_duration() to tpm2_ordinal_duration_index()
3. Move the two functions close to each other in the file.
V5: Adjust the kdoc to the new standard.

drivers/char/tpm/tpm.h | 41 +++++---
drivers/char/tpm/tpm2-cmd.c | 241 +++++++++++++++++---------------------------
2 files changed, 118 insertions(+), 164 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..f08478c78bf7 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -40,129 +40,100 @@ static struct tpm2_hash tpm2_hash_map[] = {
{HASH_ALGO_SM3_256, TPM2_ALG_SM3_256},
};

-/*
- * Array with one entry per ordinal defining 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.
- * LONG_LONG is for commands that generates keys which empirically
- * takes longer time on some systems.
+/**
+ * tpm2_ordinal_duration_index() - returns an index to the chip duration table
+ * @ordinal: TPM command ordinal.
+ *
+ * The function returns an index to the chip duration table
+ * (enum tpm_duration), that describes the maximum amount of
+ * time the chip could take to return the result for a particular ordinal.
+ *
+ * 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
+ * a longer time on some systems.
+ *
+ * Return:
+ * * TPM_MEDIUM
+ * * TPM_LONG,
+ * * TPM_LONG_LONG
+ * * TPM_UNDEFINED.
*/
-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_index(u32 ordinal)
+{
+ switch (ordinal) {
+ /* Startup */
+ case TPM2_CC_STARTUP: /* 144 */
+ return TPM_MEDIUM;
+
+ case TPM2_CC_SELF_TEST: /* 143 */
+ return TPM_LONG;
+
+ case TPM2_CC_GET_RANDOM: /* 17B */
+ return TPM_LONG;
+
+ 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;
+
+ case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
+ return TPM_LONG;
+
+ case TPM2_CC_PCR_EXTEND: /* 182 */
+ return TPM_MEDIUM;
+
+ case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
+ return TPM_LONG;
+ case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
+ return TPM_LONG;
+
+ case TPM2_CC_GET_CAPABILITY: /* 17A */
+ return TPM_MEDIUM;
+
+ case TPM2_CC_NV_READ: /* 14E */
+ return TPM_LONG;
+
+ 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;
+ }
+}
+
+/**
+ * tpm2_calc_ordinal_duration() - calculate the maximum command duration
+ * @chip: TPM chip to use.
+ * @ordinal: TPM command ordinal.
+ *
+ * The function returns the maximum amount of time the chip could take
+ * to return the result for a particular ordinal in jiffies.
+ *
+ * Return: A maximal duration time for an ordinal in jiffies.
+ */
+unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+{
+ unsigned int index;
+
+ index = tpm2_ordinal_duration_index(ordinal);
+
+ if (index != TPM_UNDEFINED)
+ return chip->duration[index];
+ else
+ return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
+}
+EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
+

struct tpm2_pcr_read_out {
__be32 update_cnt;
@@ -748,32 +719,6 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
tpm_buf_destroy(&buf);
}

-/*
- * tpm2_calc_ordinal_duration() - maximum duration for a command
- *
- * @chip: TPM chip to use.
- * @ordinal: command code number.
- *
- * Return: maximum duration for a command
- */
-unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
-{
- int index = TPM_UNDEFINED;
- int duration = 0;
-
- if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST)
- index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST];
-
- if (index != TPM_UNDEFINED)
- duration = chip->duration[index];
-
- if (duration <= 0)
- duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT);
-
- return duration;
-}
-EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
-
/**
* tpm2_do_selftest() - ensure that all self tests have passed
*
--
2.14.4


2018-09-28 22:36:48

by Tomas Winkler

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

The commit:
"tpm_tis: further simplify calculation of ordinal duration"
left unused macros, we can drop them now.

Fixes compilation warnings:
tpm-interface.c:37:0: warning: macro "TPM_PROTECTED_COMMAND" is not used [-Wunused-macros]
tpm-interface.c:36:0: warning: macro "TSC_MAX_ORDINAL" is not used [-Wunused-macros]
tpm-interface.c:38:0: warning: macro "TPM_CONNECTION_COMMAND" is not used [-Wunused-macros]

Fixes: f72864300139 ("tpm_tis: further simplify calculation of ordinal duration")
Signed-off-by: Tomas Winkler <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
---

V3: New in the series.
V4: Fix the commit message.
V5: Resend.

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 fb142e229f95..98f9a0bbeed9 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-28 22:36:55

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 13/21] tpm: add tpm_auto_startup() into tpm-interface.c

Add wrapper tpm_auto_startup() to tpm-interface.c
instead of open coded decision between TPM 1.x and TPM 2.x
in tpm-chip.c

Signed-off-by: Tomas Winkler <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---

V3: New in the series.
V4: Fix the commit message.
V5: Resend.

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 1ea83a3f1b02..fb142e229f95 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -530,6 +530,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-28 22:37:00

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 18/21] tmp1: rename tpm1_pcr_read_dev to tpm1_pcr_read().

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

Signed-off-by: Tomas Winkler <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
---
V4: New in the series
V5: Resend.

drivers/char/tpm/tpm-interface.c | 2 +-
drivers/char/tpm/tpm-sysfs.c | 2 +-
drivers/char/tpm/tpm.h | 2 +-
drivers/char/tpm/tpm1-cmd.c | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 0af71d53d129..3d80c5114fec 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -465,7 +465,7 @@ int tpm_pcr_read(struct tpm_chip *chip, 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..96fc7433c57d 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 = 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..2f06740f993d 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -525,7 +525,7 @@ 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);
+int tpm1_pcr_read(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);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index d30f336518f6..05b772477bac 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -572,7 +572,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, int pcr_idx, u8 *res_buf)
{
struct tpm_buf buf;
int rc;
@@ -660,7 +660,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
--
2.14.4


2018-09-28 22:37:02

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 12/21] 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 to __tpm2_pcr_extend() and made static, it is called
only from new tpm2_pcr_extend().

Fix warnings in __tpm2_pcr_extend()
tpm2-cmd.c:251:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
tpm2-cmd.c:252:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

Signed-off-by: Tomas Winkler <[email protected]>
---
V3: Fix the commit message.
V4: 1. Fix the kdoc.
2. Fix the commit message.
3. Fix compilation warnings.
V5: A small fix in the kdoc.

drivers/char/tpm/tpm-interface.c | 24 +++++----------------
drivers/char/tpm/tpm.h | 3 +--
drivers/char/tpm/tpm1-cmd.c | 2 +-
drivers/char/tpm/tpm2-cmd.c | 46 +++++++++++++++++++++++++++++++---------
4 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index d33060511a27..1ea83a3f1b02 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -491,31 +491,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 5b2e743a3e51..8a84db315676 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -312,7 +312,7 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
#define TPM_ST_CLEAR 1

/**
- * tpm_startup - turn on the TPM
+ * tpm_startup() - turn on the TPM
* @chip: TPM chip to use
*
* Normally the firmware should start the TPM. This function is provided as a
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index a3d39360620f..2b705b00db78 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -216,23 +216,21 @@ struct tpm2_null_auth_area {
} __packed;

/**
- * tpm2_pcr_extend() - extend a PCR value
- *
- * @chip: TPM chip to use.
- * @pcr_idx: index of the PCR.
- * @count: number of digests passed.
- * @digests: list of pcr banks and corresponding digest values to extend.
+ * __tpm2_pcr_extend() - extend a PCR value
+ * @chip: TPM chip to use.
+ * @pcr_idx: index of the PCR.
+ * @count: number of digests passed.
+ * @digests: list of pcr banks and corresponding digest values to extend.
*
* 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;
+ u32 i, j;
int rc;
- int i;
- int j;

if (count > ARRAY_SIZE(chip->active_banks))
return -EINVAL;
@@ -272,6 +270,34 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
return rc;
}

+/**
+ * tpm2_pcr_extend() - extend a PCR value
+ * @chip: TPM chip to use.
+ * @pcr_idx: index of the PCR to extend.
+ * @hash: the hash of a measurement.
+ *
+ * Return: Same as with tpm_transmit_cmd.
+ */
+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-28 22:37:13

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 10/21] tpm: factor out tpm 1.x pm suspend flow into tpm1-cmd.c

Factor out TPM 1.x 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
V4: 1. Add kdoc for tpm1_pm_suspend().
2. Fix commit message.
V5: Adjust the kdoc to the new standard.

drivers/char/tpm/tpm-interface.c | 55 ++++--------------------------------
drivers/char/tpm/tpm.h | 1 +
drivers/char/tpm/tpm1-cmd.c | 61 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 50 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 70b20b4c789a..25242190a941 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -585,15 +585,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.
@@ -601,54 +592,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 a69a02366c32..3bd9f1fa77ce 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -666,3 +666,64 @@ 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)
+};
+
+/**
+ * tpm1_pm_suspend() - pm suspend handler
+ * @chip: TPM chip to use.
+ * @tpm_suspend_pcr: flush pcr for buggy TPM chips.
+ *
+ * The functions saves the TPM state to be restored on resume.
+ *
+ * Return:
+ * * 0 on success,
+ * * < 0 on error.
+ */
+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-28 22:37:14

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 05/21] 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]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V2-V3: Rebase
V4: Fix the commit message.
V5: Resend.

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 305eb3069101..1fa0300f3829 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -502,132 +502,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 dfbe9c60cbcf..978946748ea3 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)
else
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 5e7bf8842be0..49df54b0e210 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -40,6 +40,28 @@ static struct tpm2_hash tpm2_hash_map[] = {
{HASH_ALGO_SM3_256, TPM2_ALG_SM3_256},
};

+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_ordinal_duration_index() - returns an index to the chip duration table
* @ordinal: TPM command ordinal.
--
2.14.4


2018-09-28 22:37:26

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 20/21] 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.

Cc: Nayna Jain <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---

V3: New in the series.
V4: Resend.
V5: Fix &buf.data -> buf.data in tpm1_continue_selftest()

drivers/char/tpm/tpm.h | 9 ---------
drivers/char/tpm/tpm1-cmd.c | 21 ++++++++++-----------
2 files changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 2f06740f993d..7ada00f067f1 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 d418a27a75e0..6b04648f8184 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -602,15 +602,8 @@ int tpm1_pcr_read(struct tpm_chip *chip, int 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
+ * 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
@@ -618,12 +611,18 @@ 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-28 22:37:28

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 07/21] 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]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V2-V3: Rebase
V4-V5: Resend

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 ac73e6ac3d83..a94a88f9f91c 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -454,52 +454,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)
@@ -857,6 +811,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 ec242397e6dc..3bd079587ef5 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -314,15 +314,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;

@@ -434,3 +434,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-28 22:37:34

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 04/21] 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]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V2-V3: Rebase.
V4: Add Kdoc.
V5: Adjust the kdoc to the new standard.

drivers/char/tpm/st33zp24/st33zp24.c | 2 +-
drivers/char/tpm/tpm-interface.c | 24 ++++++++++++++++++++----
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, 25 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..305eb3069101 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -47,6 +47,25 @@ 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.");

+/**
+ * tpm_calc_ordinal_duration() - calculate the maximum command duration
+ * @chip: TPM chip to use.
+ * @ordinal: TPM command ordinal.
+ *
+ * The function returns the maximum amount of time the chip could take
+ * to return the result for a particular ordinal in jiffies.
+ *
+ * Return: A maximal duration time for an ordinal in jiffies.
+ */
+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 +239,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 991260134659..dfbe9c60cbcf 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -307,4 +307,3 @@ 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 f08478c78bf7..5e7bf8842be0 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -132,7 +132,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);


struct tpm2_pcr_read_out {
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 77097229bf49..b150f87f38f5 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-28 22:37:38

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 08/21] 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]>
Reviewed-by: Jarkko Sakkine <[email protected]>
---
V2-V3: Rebase
V4-V5: Resend

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 a94a88f9f91c..a2205f26c74c 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -811,14 +811,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
@@ -829,58 +821,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 3bd079587ef5..e02f0c1c822f 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -469,3 +469,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-28 22:37:53

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 03/21] 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]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V2-V3: Rebase
V4: 1. Remove the licence statement it's already covered by SPDX.
2. Add kdoc to tpm1_calc_ordinal_duration().
V5: Adjust the kdoc to the new standard.

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..991260134659
--- /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
+ */
+
+#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,
+};
+
+/**
+ * tpm1_calc_ordinal_duration() - calculate the maximum command duration
+ * @chip: TPM chip to use.
+ * @ordinal: TPM command ordinal.
+ *
+ * The function returns the maximum amount of time the chip could take
+ * to return the result for a particular ordinal in jiffies.
+ *
+ * Return: A maximal duration time for an ordinal in jiffies.
+ */
+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 b150f87f38f5..77097229bf49 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-28 22:38:23

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 11/21] tpm: factor out tpm_startup function

TPM manual startup is used only from within TPM 1.x or TPM 2.x
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]>
Tested-by: Jarkko Sakkinen <[email protected]>
---
V2-V2: Resend.
V4: Fix the commit message.
V5: 1. A small fix in the kdoc.
2. Fixed Jarkko's name in Tested-by.

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 25242190a941..d33060511a27 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -413,47 +413,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 3bd9f1fa77ce..5b2e743a3e51 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -308,6 +308,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;
@@ -317,7 +351,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,
@@ -727,3 +761,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 49df54b0e210..a3d39360620f 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -948,6 +948,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
@@ -959,7 +989,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;

@@ -968,7 +998,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-28 22:38:36

by Tomas Winkler

[permalink] [raw]
Subject: [PATCH v5 09/21] tpm: move tpm 1.x selftest code from tpm-interface.c 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]>
Tested-by: Jarkko Sakkinen <[email protected]>
Reviewed-by: Jarkko Sakkinen <[email protected]>
---

V2-V3: Rebase
V4: Fix the commit message.
V5: Resend.

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 a2205f26c74c..70b20b4c789a 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -466,59 +466,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
@@ -559,10 +506,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;
}
@@ -613,97 +562,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 e02f0c1c822f..a69a02366c32 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -524,3 +524,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-28 22:38:59

by Tomas Winkler

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

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

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]>
---

V2-V3: Rebase
V4: Remove defines.
V5: Resend.

drivers/char/tpm/tpm-interface.c | 28 ----------------------------
drivers/char/tpm/tpm.h | 2 ++
drivers/char/tpm/tpm1-cmd.c | 21 +++++++++++++++++++++
3 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 1fa0300f3829..ac73e6ac3d83 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -614,34 +614,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 978946748ea3..ec242397e6dc 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -413,3 +413,24 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
return 0;
}
+
+#define TPM_ORD_PCR_EXTEND 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, PAGE_SIZE,
+ TPM_DIGEST_SIZE, 0, log_msg);
+
+ tpm_buf_destroy(&buf);
+ return rc;
+}
--
2.14.4


2018-10-02 00:39:56

by Jarkko Sakkinen

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

Looks good. Just some minor bits.

On Sat, Sep 29, 2018 at 01:30:15AM +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, the switch statement function
> is called tpm2_ordinal_duration_index().
> 3. Fix kdoc comments for tpm2_calc_ordinal_duration().
>
> Signed-off-by: Tomas Winkler <[email protected]>
> Tested-by: Jarkko Sakkinen <[email protected]>
> ---
>
> V2-V3: Rebase.
> V4: 1. Fix kdoc
> 2. Rename tpm2_ordinal_duration() to tpm2_ordinal_duration_index()
> 3. Move the two functions close to each other in the file.
> V5: Adjust the kdoc to the new standard.
>
> drivers/char/tpm/tpm.h | 41 +++++---
> drivers/char/tpm/tpm2-cmd.c | 241 +++++++++++++++++---------------------------
> 2 files changed, 118 insertions(+), 164 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..f08478c78bf7 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -40,129 +40,100 @@ static struct tpm2_hash tpm2_hash_map[] = {
> {HASH_ALGO_SM3_256, TPM2_ALG_SM3_256},
> };
>
> -/*
> - * Array with one entry per ordinal defining 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.
> - * LONG_LONG is for commands that generates keys which empirically
> - * takes longer time on some systems.
> +/**
> + * tpm2_ordinal_duration_index() - returns an index to the chip duration table
> + * @ordinal: TPM command ordinal.
> + *
> + * The function returns an index to the chip duration table
> + * (enum tpm_duration), that describes the maximum amount of
> + * time the chip could take to return the result for a particular ordinal.
> + *
> + * 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
> + * a longer time on some systems.
> + *
> + * Return:
> + * * TPM_MEDIUM

A semicolon missing.

> + * * TPM_LONG,
> + * * TPM_LONG_LONG

A semicolon missing.

> + * * TPM_UNDEFINED.
> */
> -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_index(u32 ordinal)
> +{
> + switch (ordinal) {
> + /* Startup */
> + case TPM2_CC_STARTUP: /* 144 */
> + return TPM_MEDIUM;
> +
> + case TPM2_CC_SELF_TEST: /* 143 */
> + return TPM_LONG;
> +
> + case TPM2_CC_GET_RANDOM: /* 17B */
> + return TPM_LONG;
> +
> + 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;
> +
> + case TPM2_CC_VERIFY_SIGNATURE: /* 177 */
> + return TPM_LONG;
> +
> + case TPM2_CC_PCR_EXTEND: /* 182 */
> + return TPM_MEDIUM;
> +
> + case TPM2_CC_HIERARCHY_CONTROL: /* 121 */
> + return TPM_LONG;
> + case TPM2_CC_HIERARCHY_CHANGE_AUTH: /* 129 */
> + return TPM_LONG;
> +
> + case TPM2_CC_GET_CAPABILITY: /* 17A */
> + return TPM_MEDIUM;
> +
> + case TPM2_CC_NV_READ: /* 14E */
> + return TPM_LONG;
> +
> + 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;
> + }
> +}
> +
> +/**
> + * tpm2_calc_ordinal_duration() - calculate the maximum command duration
> + * @chip: TPM chip to use.
> + * @ordinal: TPM command ordinal.
> + *
> + * The function returns the maximum amount of time the chip could take
> + * to return the result for a particular ordinal in jiffies.
> + *
> + * Return: A maximal duration time for an ordinal in jiffies.
> + */
> +unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
> +{
> + unsigned int index;
> +
> + index = tpm2_ordinal_duration_index(ordinal);
> +
> + if (index != TPM_UNDEFINED)
> + return chip->duration[index];
> + else
> + return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
> +}
> +EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
> +
>
> struct tpm2_pcr_read_out {
> __be32 update_cnt;
> @@ -748,32 +719,6 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
> tpm_buf_destroy(&buf);
> }
>
> -/*
> - * tpm2_calc_ordinal_duration() - maximum duration for a command
> - *
> - * @chip: TPM chip to use.
> - * @ordinal: command code number.
> - *
> - * Return: maximum duration for a command
> - */
> -unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
> -{
> - int index = TPM_UNDEFINED;
> - int duration = 0;
> -
> - if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST)
> - index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST];
> -
> - if (index != TPM_UNDEFINED)
> - duration = chip->duration[index];
> -
> - if (duration <= 0)
> - duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT);
> -
> - return duration;
> -}
> -EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
> -
> /**
> * tpm2_do_selftest() - ensure that all self tests have passed
> *
> --
> 2.14.4
>

/Jarkko

2018-10-02 00:42:12

by Jarkko Sakkinen

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

On Sat, Sep 29, 2018 at 01:30:15AM +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, the switch statement function
> is called tpm2_ordinal_duration_index().
> 3. Fix kdoc comments for tpm2_calc_ordinal_duration().
>
> Signed-off-by: Tomas Winkler <[email protected]>
> Tested-by: Jarkko Sakkinen <[email protected]>
> ---
>
> V2-V3: Rebase.
> V4: 1. Fix kdoc
> 2. Rename tpm2_ordinal_duration() to tpm2_ordinal_duration_index()
> 3. Move the two functions close to each other in the file.
> V5: Adjust the kdoc to the new standard.

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

/Jarkko

2018-10-02 00:43:15

by Jarkko Sakkinen

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

On Sat, Sep 29, 2018 at 01:30:20AM +0300, Tomas Winkler wrote:
> Move tpm1_pcr_extend to tpm1-cmd.c and remove
> unused pcrextend_header structure and
> EXTEND_PCR_RESULT_SIZE and EXTEND_PCR_RESULT_BODY_SIZE
> defines.
>
> 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]>

Would need help with this from someone with a working IMA setup
on testing.

/Jarkko

2018-10-02 00:44:18

by Jarkko Sakkinen

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

On Sat, Sep 29, 2018 at 01:30:22AM +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]>

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

/Jarkko

2018-10-02 00:45:23

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v5 00/21] tpm: separate tpm 1.x and tpm 2.x commands

On Sat, Sep 29, 2018 at 01:30:14AM +0300, Tomas Winkler wrote:
> 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.

Would be nice if the change log was here and not scattered into
patches.

/Jarkko

2018-10-02 00:46:42

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v5 11/21] tpm: factor out tpm_startup function

On Sat, Sep 29, 2018 at 01:30:25AM +0300, Tomas Winkler wrote:
> TPM manual startup is used only from within TPM 1.x or TPM 2.x
> 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]>
> Tested-by: Jarkko Sakkinen <[email protected]>

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

/Jarkko

2018-10-02 00:47:39

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v5 10/21] tpm: factor out tpm 1.x pm suspend flow into tpm1-cmd.c

On Sat, Sep 29, 2018 at 01:30:24AM +0300, Tomas Winkler wrote:
> Factor out TPM 1.x suspend flow from tpm-interface.c into a new function
> tpm1_pm_suspend() in tpm1-cmd.c
>
> Signed-off-by: Tomas Winkler <[email protected]>

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

/Jarkko

2018-10-02 00:52:48

by Jarkko Sakkinen

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

On Sat, Sep 29, 2018 at 01:30:26AM +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 to __tpm2_pcr_extend() and made static, it is called
> only from new tpm2_pcr_extend().
>
> Fix warnings in __tpm2_pcr_extend()
> tpm2-cmd.c:251:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
> tpm2-cmd.c:252:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
>
> Signed-off-by: Tomas Winkler <[email protected]>

We do not want the signature change, especially because as we are
working on getting Roberto's changes in and also because it has
absolutely a zero gain. Who cares if those functions take different
parameters? I don't.

/Jarkko

2018-10-02 00:57:42

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v5 13/21] tpm: add tpm_auto_startup() into tpm-interface.c

On Sat, Sep 29, 2018 at 01:30:27AM +0300, Tomas Winkler wrote:
> Add wrapper tpm_auto_startup() to tpm-interface.c
> instead of open coded decision between TPM 1.x and TPM 2.x
> in tpm-chip.c
>
> Signed-off-by: Tomas Winkler <[email protected]>
> Tested-by: Jarkko Sakkinen <[email protected]>

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

/Jarkko

2018-10-02 00:59:04

by Jarkko Sakkinen

[permalink] [raw]
Subject: Re: [PATCH v5 21/21] tpm: use u32 instead of int for PCR index

On Sat, Sep 29, 2018 at 01:30:35AM +0300, Tomas Winkler wrote:
> The TPM specs defines PCR index as a positive number, and there is
> no reason to use a signed number. It is also a possible security
> issue as currently no functions check for a negative index,
> which may become a large number when converted to u32.
>
> Adjust the API to use u32 instead of int in all PCR related
> functions.
>
> Signed-off-by: Tomas Winkler <[email protected]>
> Reviewed-by: Jarkko Sakkinen <[email protected]>

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

/Jarkko

2018-10-02 05:00:58

by Tomas Winkler

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



>
> On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> > __tpm2_pcr_extend() and made static, it is called only from new
> > tpm2_pcr_extend().
> >
> > Fix warnings in __tpm2_pcr_extend()
> > tpm2-cmd.c:251:16: warning: comparison between signed and unsigned
> > integer expressions [-Wsign-compare]
> > tpm2-cmd.c:252:17: warning: comparison between signed and unsigned
> > integer expressions [-Wsign-compare]
> >
> > Signed-off-by: Tomas Winkler <[email protected]>
>
> We do not want the signature change, especially because as we are working
> on getting Roberto's changes in and also because it has absolutely a zero
> gain. Who cares if those functions take different parameters? I don't.

Yes, we do care this series tries to have a clean cut between 1.x and 2.x specs. Please, let's finish one transformation and then move to another.
I understand that Roberto will have to rebase anyhow, if this series goes in first, if this is hard I can do it myself, it's trivial.

Tomas


2018-10-02 09:33:02

by Nayna Jain

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



On 10/02/2018 06:12 AM, Jarkko Sakkinen wrote:
> On Sat, Sep 29, 2018 at 01:30:20AM +0300, Tomas Winkler wrote:
>> Move tpm1_pcr_extend to tpm1-cmd.c and remove
>> unused pcrextend_header structure and
>> EXTEND_PCR_RESULT_SIZE and EXTEND_PCR_RESULT_BODY_SIZE
>> defines.
>>
>> 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]>
> Would need help with this from someone with a working IMA setup
> on testing.


My test system is down for now.. I think it will be up later in this
week. I can test it then.

Thanks & Regards,
    - Nayna


>
> /Jarkko
>


2018-10-03 12:02:40

by Jarkko Sakkinen

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

On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
>
>
> >
> > On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> > > __tpm2_pcr_extend() and made static, it is called only from new
> > > tpm2_pcr_extend().
> > >
> > > Fix warnings in __tpm2_pcr_extend()
> > > tpm2-cmd.c:251:16: warning: comparison between signed and unsigned
> > > integer expressions [-Wsign-compare]
> > > tpm2-cmd.c:252:17: warning: comparison between signed and unsigned
> > > integer expressions [-Wsign-compare]
> > >
> > > Signed-off-by: Tomas Winkler <[email protected]>
> >
> > We do not want the signature change, especially because as we are working
> > on getting Roberto's changes in and also because it has absolutely a zero
> > gain. Who cares if those functions take different parameters? I don't.
>
> Yes, we do care this series tries to have a clean cut between 1.x and 2.x specs. Please, let's finish one transformation and then move to another.
> I understand that Roberto will have to rebase anyhow, if this series goes in first, if this is hard I can do it myself, it's trivial.
>
> Tomas

I'm happy to tune this minor stuff. I'll wait for Nayna to test
the one patch and make those adjustments :-) Would not make sense
to roll another series for these changes.

/Jarkko

2018-10-03 12:04:10

by Jarkko Sakkinen

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

On Tue, Oct 02, 2018 at 02:58:00PM +0530, Nayna Jain wrote:
>
>
> On 10/02/2018 06:12 AM, Jarkko Sakkinen wrote:
> > On Sat, Sep 29, 2018 at 01:30:20AM +0300, Tomas Winkler wrote:
> > > Move tpm1_pcr_extend to tpm1-cmd.c and remove
> > > unused pcrextend_header structure and
> > > EXTEND_PCR_RESULT_SIZE and EXTEND_PCR_RESULT_BODY_SIZE
> > > defines.
> > >
> > > 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]>
> > Would need help with this from someone with a working IMA setup
> > on testing.
>
>
> My test system is down for now.. I think it will be up later in this week. I
> can test it then.

Thank you.

/Jarkko

2018-10-03 22:27:35

by Tomas Winkler

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



> -----Original Message-----
> From: Jarkko Sakkinen [mailto:[email protected]]
> Sent: Wednesday, October 03, 2018 15:02
> To: Winkler, Tomas <[email protected]>
> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> <[email protected]>; Usyskin, Alexander
> <[email protected]>; Struk, Tadeusz <[email protected]>;
> [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
>
> On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
> >
> >
> > >
> > > On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> > > > __tpm2_pcr_extend() and made static, it is called only from new
> > > > tpm2_pcr_extend().
> > > >
> > > > Fix warnings in __tpm2_pcr_extend()
> > > > tpm2-cmd.c:251:16: warning: comparison between signed and unsigned
> > > > integer expressions [-Wsign-compare]
> > > > tpm2-cmd.c:252:17: warning: comparison between signed and unsigned
> > > > integer expressions [-Wsign-compare]
> > > >
> > > > Signed-off-by: Tomas Winkler <[email protected]>
> > >
> > > We do not want the signature change, especially because as we are
> > > working on getting Roberto's changes in and also because it has
> > > absolutely a zero gain. Who cares if those functions take different
> parameters? I don't.
> >
> > Yes, we do care this series tries to have a clean cut between 1.x and 2.x
> specs. Please, let's finish one transformation and then move to another.
> > I understand that Roberto will have to rebase anyhow, if this series goes in
> first, if this is hard I can do it myself, it's trivial.
> >
> > Tomas
>
> I'm happy to tune this minor stuff.
What minor stuff? This patch is just okay, let's change the API in next round.

I'll wait for Nayna to test the one patch
> and make those adjustments :-) Would not make sense to roll another series
> for these changes.
I agree
Tomas


2018-10-04 11:35:31

by Jarkko Sakkinen

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

On Wed, Oct 03, 2018 at 10:24:09PM +0000, Winkler, Tomas wrote:
>
>
> > -----Original Message-----
> > From: Jarkko Sakkinen [mailto:[email protected]]
> > Sent: Wednesday, October 03, 2018 15:02
> > To: Winkler, Tomas <[email protected]>
> > Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> > <[email protected]>; Usyskin, Alexander
> > <[email protected]>; Struk, Tadeusz <[email protected]>;
> > [email protected]; [email protected];
> > [email protected]; [email protected]
> > Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
> >
> > On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
> > >
> > >
> > > >
> > > > On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> > > > > __tpm2_pcr_extend() and made static, it is called only from new
> > > > > tpm2_pcr_extend().
> > > > >
> > > > > Fix warnings in __tpm2_pcr_extend()
> > > > > tpm2-cmd.c:251:16: warning: comparison between signed and unsigned
> > > > > integer expressions [-Wsign-compare]
> > > > > tpm2-cmd.c:252:17: warning: comparison between signed and unsigned
> > > > > integer expressions [-Wsign-compare]
> > > > >
> > > > > Signed-off-by: Tomas Winkler <[email protected]>
> > > >
> > > > We do not want the signature change, especially because as we are
> > > > working on getting Roberto's changes in and also because it has
> > > > absolutely a zero gain. Who cares if those functions take different
> > parameters? I don't.
> > >
> > > Yes, we do care this series tries to have a clean cut between 1.x and 2.x
> > specs. Please, let's finish one transformation and then move to another.
> > > I understand that Roberto will have to rebase anyhow, if this series goes in
> > first, if this is hard I can do it myself, it's trivial.
> > >
> > > Tomas
> >
> > I'm happy to tune this minor stuff.
> What minor stuff? This patch is just okay, let's change the API in next round.

The patch is not okay because it does a completely unnecessary API
change.

/Jarkko

2018-10-04 11:40:17

by Jarkko Sakkinen

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

On Thu, Oct 04, 2018 at 02:35:02PM +0300, Jarkko Sakkinen wrote:
> On Wed, Oct 03, 2018 at 10:24:09PM +0000, Winkler, Tomas wrote:
> >
> >
> > > -----Original Message-----
> > > From: Jarkko Sakkinen [mailto:[email protected]]
> > > Sent: Wednesday, October 03, 2018 15:02
> > > To: Winkler, Tomas <[email protected]>
> > > Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> > > <[email protected]>; Usyskin, Alexander
> > > <[email protected]>; Struk, Tadeusz <[email protected]>;
> > > [email protected]; [email protected];
> > > [email protected]; [email protected]
> > > Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
> > >
> > > On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
> > > >
> > > >
> > > > >
> > > > > On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> > > > > > __tpm2_pcr_extend() and made static, it is called only from new
> > > > > > tpm2_pcr_extend().
> > > > > >
> > > > > > Fix warnings in __tpm2_pcr_extend()
> > > > > > tpm2-cmd.c:251:16: warning: comparison between signed and unsigned
> > > > > > integer expressions [-Wsign-compare]
> > > > > > tpm2-cmd.c:252:17: warning: comparison between signed and unsigned
> > > > > > integer expressions [-Wsign-compare]
> > > > > >
> > > > > > Signed-off-by: Tomas Winkler <[email protected]>
> > > > >
> > > > > We do not want the signature change, especially because as we are
> > > > > working on getting Roberto's changes in and also because it has
> > > > > absolutely a zero gain. Who cares if those functions take different
> > > parameters? I don't.
> > > >
> > > > Yes, we do care this series tries to have a clean cut between 1.x and 2.x
> > > specs. Please, let's finish one transformation and then move to another.
> > > > I understand that Roberto will have to rebase anyhow, if this series goes in
> > > first, if this is hard I can do it myself, it's trivial.
> > > >
> > > > Tomas
> > >
> > > I'm happy to tune this minor stuff.
> > What minor stuff? This patch is just okay, let's change the API in next round.
>
> The patch is not okay because it does a completely unnecessary API
> change.

Other minor stuff was missing commas in the list of return values if I
recall...

/Jarkko

2018-10-04 11:46:09

by Tomas Winkler

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



> -----Original Message-----
> From: Jarkko Sakkinen [mailto:[email protected]]
> Sent: Thursday, October 04, 2018 14:35
> To: Winkler, Tomas <[email protected]>
> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> <[email protected]>; Usyskin, Alexander
> <[email protected]>; Struk, Tadeusz <[email protected]>;
> [email protected]; [email protected];
> [email protected]; [email protected]
> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
>
> On Wed, Oct 03, 2018 at 10:24:09PM +0000, Winkler, Tomas wrote:
> >
> >
> > > -----Original Message-----
> > > From: Jarkko Sakkinen [mailto:[email protected]]
> > > Sent: Wednesday, October 03, 2018 15:02
> > > To: Winkler, Tomas <[email protected]>
> > > Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> > > <[email protected]>; Usyskin, Alexander
> > > <[email protected]>; Struk, Tadeusz
> > > <[email protected]>; [email protected];
> > > [email protected];
> > > [email protected]; [email protected]
> > > Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to
> > > tpm2-cmd.c
> > >
> > > On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
> > > >
> > > >
> > > > >
> > > > > On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> > > > > > __tpm2_pcr_extend() and made static, it is called only from
> > > > > > new tpm2_pcr_extend().
> > > > > >
> > > > > > Fix warnings in __tpm2_pcr_extend()
> > > > > > tpm2-cmd.c:251:16: warning: comparison between signed and
> > > > > > unsigned integer expressions [-Wsign-compare]
> > > > > > tpm2-cmd.c:252:17: warning: comparison between signed and
> > > > > > unsigned integer expressions [-Wsign-compare]
> > > > > >
> > > > > > Signed-off-by: Tomas Winkler <[email protected]>
> > > > >
> > > > > We do not want the signature change, especially because as we
> > > > > are working on getting Roberto's changes in and also because it
> > > > > has absolutely a zero gain. Who cares if those functions take
> > > > > different
> > > parameters? I don't.
> > > >
> > > > Yes, we do care this series tries to have a clean cut between 1.x
> > > > and 2.x
> > > specs. Please, let's finish one transformation and then move to another.
> > > > I understand that Roberto will have to rebase anyhow, if this
> > > > series goes in
> > > first, if this is hard I can do it myself, it's trivial.
> > > >
> > > > Tomas
> > >
> > > I'm happy to tune this minor stuff.
> > What minor stuff? This patch is just okay, let's change the API in next
> round.
>
> The patch is not okay because it does a completely unnecessary API change.

There is no API change, in that sense.
The exported API is in tpm-interface.c int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
that is used is outside of the tpm reminds the same, only the open coded implementation of tpm2_pcr_extned has moved to
tpm2-cmd.c, This code is not called out of tpm module.
Please review the code again.

Thanks
Tomas



2018-10-04 12:22:05

by Roberto Sassu

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

On 10/4/2018 1:45 PM, Winkler, Tomas wrote:
>
>
>> -----Original Message-----
>> From: Jarkko Sakkinen [mailto:[email protected]]
>> Sent: Thursday, October 04, 2018 14:35
>> To: Winkler, Tomas <[email protected]>
>> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
>> <[email protected]>; Usyskin, Alexander
>> <[email protected]>; Struk, Tadeusz <[email protected]>;
>> [email protected]; [email protected];
>> [email protected]; [email protected]
>> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
>>
>> On Wed, Oct 03, 2018 at 10:24:09PM +0000, Winkler, Tomas wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Jarkko Sakkinen [mailto:[email protected]]
>>>> Sent: Wednesday, October 03, 2018 15:02
>>>> To: Winkler, Tomas <[email protected]>
>>>> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
>>>> <[email protected]>; Usyskin, Alexander
>>>> <[email protected]>; Struk, Tadeusz
>>>> <[email protected]>; [email protected];
>>>> [email protected];
>>>> [email protected]; [email protected]
>>>> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to
>>>> tpm2-cmd.c
>>>>
>>>> On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
>>>>>
>>>>>
>>>>>>
>>>>>> On Sat, Sep 29, 2018 at 01:30:26AM +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 to
>>>>>>> __tpm2_pcr_extend() and made static, it is called only from
>>>>>>> new tpm2_pcr_extend().
>>>>>>>
>>>>>>> Fix warnings in __tpm2_pcr_extend()
>>>>>>> tpm2-cmd.c:251:16: warning: comparison between signed and
>>>>>>> unsigned integer expressions [-Wsign-compare]
>>>>>>> tpm2-cmd.c:252:17: warning: comparison between signed and
>>>>>>> unsigned integer expressions [-Wsign-compare]
>>>>>>>
>>>>>>> Signed-off-by: Tomas Winkler <[email protected]>
>>>>>>
>>>>>> We do not want the signature change, especially because as we
>>>>>> are working on getting Roberto's changes in and also because it
>>>>>> has absolutely a zero gain. Who cares if those functions take
>>>>>> different
>>>> parameters? I don't.
>>>>>
>>>>> Yes, we do care this series tries to have a clean cut between 1.x
>>>>> and 2.x
>>>> specs. Please, let's finish one transformation and then move to another.
>>>>> I understand that Roberto will have to rebase anyhow, if this
>>>>> series goes in
>>>> first, if this is hard I can do it myself, it's trivial.
>>>>>
>>>>> Tomas
>>>>
>>>> I'm happy to tune this minor stuff.
>>> What minor stuff? This patch is just okay, let's change the API in next
>> round.
>>
>> The patch is not okay because it does a completely unnecessary API change.
>
> There is no API change, in that sense.
> The exported API is in tpm-interface.c int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
> that is used is outside of the tpm reminds the same, only the open coded implementation of tpm2_pcr_extned has moved to
> tpm2-cmd.c, This code is not called out of tpm module.
> Please review the code again.

Hi Tomas

I will update tpm_pcr_extend() by replacing the array of u8 with an
array of tpm2_digest structures, so that the caller can provide multiple
digests with one call. The array of tpm2_digest structures will be
passed to tpm2_pcr_extend(). Please, don't modify the parameters of
tpm2_pcr_extend().

Thanks

Roberto

--
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Jian LI, Yanli SHI

2018-10-04 13:46:37

by Tomas Winkler

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

>
> On 10/4/2018 1:45 PM, Winkler, Tomas wrote:
> >
> >
> >> -----Original Message-----
> >> From: Jarkko Sakkinen [mailto:[email protected]]
> >> Sent: Thursday, October 04, 2018 14:35
> >> To: Winkler, Tomas <[email protected]>
> >> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> >> <[email protected]>; Usyskin, Alexander
> >> <[email protected]>; Struk, Tadeusz
> >> <[email protected]>; [email protected];
> >> [email protected];
> >> [email protected]; [email protected]
> >> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
> >>
> >> On Wed, Oct 03, 2018 at 10:24:09PM +0000, Winkler, Tomas wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Jarkko Sakkinen [mailto:[email protected]]
> >>>> Sent: Wednesday, October 03, 2018 15:02
> >>>> To: Winkler, Tomas <[email protected]>
> >>>> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
> >>>> <[email protected]>; Usyskin, Alexander
> >>>> <[email protected]>; Struk, Tadeusz
> >>>> <[email protected]>; [email protected];
> >>>> [email protected];
> >>>> [email protected]; [email protected]
> >>>> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to
> >>>> tpm2-cmd.c
> >>>>
> >>>> On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
> >>>>>
> >>>>>
> >>>>>>
> >>>>>> On Sat, Sep 29, 2018 at 01:30:26AM +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 to
> >>>>>>> __tpm2_pcr_extend() and made static, it is called only from new
> >>>>>>> tpm2_pcr_extend().
> >>>>>>>
> >>>>>>> Fix warnings in __tpm2_pcr_extend()
> >>>>>>> tpm2-cmd.c:251:16: warning: comparison between signed and
> >>>>>>> unsigned integer expressions [-Wsign-compare]
> >>>>>>> tpm2-cmd.c:252:17: warning: comparison between signed and
> >>>>>>> unsigned integer expressions [-Wsign-compare]
> >>>>>>>
> >>>>>>> Signed-off-by: Tomas Winkler <[email protected]>
> >>>>>>
> >>>>>> We do not want the signature change, especially because as we are
> >>>>>> working on getting Roberto's changes in and also because it has
> >>>>>> absolutely a zero gain. Who cares if those functions take
> >>>>>> different
> >>>> parameters? I don't.
> >>>>>
> >>>>> Yes, we do care this series tries to have a clean cut between 1.x
> >>>>> and 2.x
> >>>> specs. Please, let's finish one transformation and then move to
> another.
> >>>>> I understand that Roberto will have to rebase anyhow, if this
> >>>>> series goes in
> >>>> first, if this is hard I can do it myself, it's trivial.
> >>>>>
> >>>>> Tomas
> >>>>
> >>>> I'm happy to tune this minor stuff.
> >>> What minor stuff? This patch is just okay, let's change the API in
> >>> next
> >> round.
> >>
> >> The patch is not okay because it does a completely unnecessary API
> change.
> >
> > There is no API change, in that sense.
> > The exported API is in tpm-interface.c int tpm_pcr_extend(struct
> > tpm_chip *chip, int pcr_idx, const u8 *hash) that is used is outside
> > of the tpm reminds the same, only the open coded implementation of
> tpm2_pcr_extned has moved to tpm2-cmd.c, This code is not called out of
> tpm module.
> > Please review the code again.
>
> Hi Tomas
>
> I will update tpm_pcr_extend() by replacing the array of u8 with an array of
> tpm2_digest structures, so that the caller can provide multiple digests with
> one call. The array of tpm2_digest structures will be passed to
> tpm2_pcr_extend(). Please, don't modify the parameters of
> tpm2_pcr_extend().

What about tpm1_pcr_extend/read()?

Thanks
Tomas

2018-10-04 14:10:30

by Roberto Sassu

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

On 10/4/2018 3:46 PM, Winkler, Tomas wrote:
>>
>> On 10/4/2018 1:45 PM, Winkler, Tomas wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Jarkko Sakkinen [mailto:[email protected]]
>>>> Sent: Thursday, October 04, 2018 14:35
>>>> To: Winkler, Tomas <[email protected]>
>>>> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
>>>> <[email protected]>; Usyskin, Alexander
>>>> <[email protected]>; Struk, Tadeusz
>>>> <[email protected]>; [email protected];
>>>> [email protected];
>>>> [email protected]; [email protected]
>>>> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to tpm2-cmd.c
>>>>
>>>> On Wed, Oct 03, 2018 at 10:24:09PM +0000, Winkler, Tomas wrote:
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Jarkko Sakkinen [mailto:[email protected]]
>>>>>> Sent: Wednesday, October 03, 2018 15:02
>>>>>> To: Winkler, Tomas <[email protected]>
>>>>>> Cc: Jason Gunthorpe <[email protected]>; Nayna Jain
>>>>>> <[email protected]>; Usyskin, Alexander
>>>>>> <[email protected]>; Struk, Tadeusz
>>>>>> <[email protected]>; [email protected];
>>>>>> [email protected];
>>>>>> [email protected]; [email protected]
>>>>>> Subject: Re: [PATCH v5 12/21] tpm: move pcr extend code to
>>>>>> tpm2-cmd.c
>>>>>>
>>>>>> On Tue, Oct 02, 2018 at 04:58:25AM +0000, Winkler, Tomas wrote:
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> On Sat, Sep 29, 2018 at 01:30:26AM +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 to
>>>>>>>>> __tpm2_pcr_extend() and made static, it is called only from new
>>>>>>>>> tpm2_pcr_extend().
>>>>>>>>>
>>>>>>>>> Fix warnings in __tpm2_pcr_extend()
>>>>>>>>> tpm2-cmd.c:251:16: warning: comparison between signed and
>>>>>>>>> unsigned integer expressions [-Wsign-compare]
>>>>>>>>> tpm2-cmd.c:252:17: warning: comparison between signed and
>>>>>>>>> unsigned integer expressions [-Wsign-compare]
>>>>>>>>>
>>>>>>>>> Signed-off-by: Tomas Winkler <[email protected]>
>>>>>>>>
>>>>>>>> We do not want the signature change, especially because as we are
>>>>>>>> working on getting Roberto's changes in and also because it has
>>>>>>>> absolutely a zero gain. Who cares if those functions take
>>>>>>>> different
>>>>>> parameters? I don't.
>>>>>>>
>>>>>>> Yes, we do care this series tries to have a clean cut between 1.x
>>>>>>> and 2.x
>>>>>> specs. Please, let's finish one transformation and then move to
>> another.
>>>>>>> I understand that Roberto will have to rebase anyhow, if this
>>>>>>> series goes in
>>>>>> first, if this is hard I can do it myself, it's trivial.
>>>>>>>
>>>>>>> Tomas
>>>>>>
>>>>>> I'm happy to tune this minor stuff.
>>>>> What minor stuff? This patch is just okay, let's change the API in
>>>>> next
>>>> round.
>>>>
>>>> The patch is not okay because it does a completely unnecessary API
>> change.
>>>
>>> There is no API change, in that sense.
>>> The exported API is in tpm-interface.c int tpm_pcr_extend(struct
>>> tpm_chip *chip, int pcr_idx, const u8 *hash) that is used is outside
>>> of the tpm reminds the same, only the open coded implementation of
>> tpm2_pcr_extned has moved to tpm2-cmd.c, This code is not called out of
>> tpm module.
>>> Please review the code again.
>>
>> Hi Tomas
>>
>> I will update tpm_pcr_extend() by replacing the array of u8 with an array of
>> tpm2_digest structures, so that the caller can provide multiple digests with
>> one call. The array of tpm2_digest structures will be passed to
>> tpm2_pcr_extend(). Please, don't modify the parameters of
>> tpm2_pcr_extend().
>
> What about tpm1_pcr_extend/read()?

tpm_pcr_extend/read() would pass to them the array of u8 from the
tpm2_digest structure. Check this patch:

[PATCH v2 2/3] tpm: modify tpm_pcr_read() definition to pass TPM hash
algorithms

Roberto

--
HUAWEI TECHNOLOGIES Duesseldorf GmbH, HRB 56063
Managing Director: Bo PENG, Jian LI, Yanli SHI

2018-10-05 11:32:41

by Jarkko Sakkinen

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

On Thu, Oct 04, 2018 at 11:45:30AM +0000, Winkler, Tomas wrote:
> There is no API change, in that sense.
> The exported API is in tpm-interface.c int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
> that is used is outside of the tpm reminds the same, only the open coded implementation of tpm2_pcr_extned has moved to
> tpm2-cmd.c, This code is not called out of tpm module.
> Please review the code again.

I did now revisit this and you are right that my choice of word was not
exactly correct. I apologize for that. The patch introduces API that we
would take away and that does make much sense.

The best way to sort things out is to just fix the warnings and leave
the TPM 2.0 part open coded inside tpm_pcr_extend(). The rationale for
this is to avoid unnecessary mainline changes when ever possible (which
is bad for backporting for stable kernels).

> Thanks
> Tomas

/Jarkko

2018-10-11 16:59:49

by Nayna Jain

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



On 09/29/2018 04:00 AM, Tomas Winkler wrote:
> +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);

The original code in the nuvoton driver does not differentiate between
TPM 1.2 and TPM 2.0 as it does in tpm_tis_core.c.  Before making any
changes, I would first fix it, so that it could easily be backported.
Only then do the refactoring

Thanks & Regards,
   - Nayna


> + 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 b150f87f38f5..77097229bf49 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) {


2018-10-11 17:06:09

by Nayna Jain

[permalink] [raw]
Subject: Re: [PATCH v5 05/21] tpm: factor out tpm_get_timeouts()



On 09/29/2018 04:00 AM, Tomas Winkler wrote:
>
> 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);

What is different in this tpm1_auto_startup(...) and the original one ?

Is this needed ?

Thanks & Regards,
   - Nayna


> +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 dfbe9c60cbcf..978946748ea3 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)
> else
> 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 5e7bf8842be0..49df54b0e210 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -40,6 +40,28 @@ static struct tpm2_hash tpm2_hash_map[] = {
> {HASH_ALGO_SM3_256, TPM2_ALG_SM3_256},
> };
>
> +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_ordinal_duration_index() - returns an index to the chip duration table
> * @ordinal: TPM command ordinal.


2018-10-11 20:20:22

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH v5 05/21] tpm: factor out tpm_get_timeouts()

On Thu, 2018-10-11 at 22:30 +0530, Nayna Jain wrote:
>
> On 09/29/2018 04:00 AM, Tomas Winkler wrote:
> >
> > 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);
>
> What is different in this tpm1_auto_startup(...) and the original one ?
>
> Is this needed ?
Looks like an amending hiccup, will fix.
Thanks
Tomas

2018-10-12 09:35:18

by Nayna Jain

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



On 09/29/2018 04:00 AM, Tomas Winkler wrote:
> Move tpm1_pcr_extend to tpm1-cmd.c and remove
> unused pcrextend_header structure and
> EXTEND_PCR_RESULT_SIZE and EXTEND_PCR_RESULT_BODY_SIZE
> defines.
>
> 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]>
> ---
>
> V2-V3: Rebase
> V4: Remove defines.
> V5: Resend.
>
> drivers/char/tpm/tpm-interface.c | 28 ----------------------------
> drivers/char/tpm/tpm.h | 2 ++
> drivers/char/tpm/tpm1-cmd.c | 21 +++++++++++++++++++++
> 3 files changed, 23 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index 1fa0300f3829..ac73e6ac3d83 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -614,34 +614,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 978946748ea3..ec242397e6dc 100644
> --- a/drivers/char/tpm/tpm1-cmd.c
> +++ b/drivers/char/tpm/tpm1-cmd.c
> @@ -413,3 +413,24 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
> chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS;
> return 0;
> }
> +
> +#define TPM_ORD_PCR_EXTEND 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, PAGE_SIZE,
> + TPM_DIGEST_SIZE, 0, log_msg);
> +
> + tpm_buf_destroy(&buf);
> + return rc;
> +}


Reviewed-by: Nayna Jain <[email protected]>
Tested-by: Nayna Jain <[email protected]>

Sorry for bit delay in testing.

Thanks & Regards,
- Nayna





2018-10-16 16:50:03

by Jarkko Sakkinen

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

On Fri, 12 Oct 2018, Nayna Jain wrote:
> Reviewed-by: Nayna Jain <[email protected]>
> Tested-by: Nayna Jain <[email protected]>
>
> Sorry for bit delay in testing.
>
> Thanks & Regards,
> - Nayna

Thank you. This is a big refactoring so your effort is highly
appreciated :-)

/Jarkko

2018-10-17 06:06:45

by Nayna Jain

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



On 09/29/2018 04:00 AM, 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.
>
> Cc: Nayna Jain <[email protected]>
> Signed-off-by: Tomas Winkler <[email protected]>
> Reviewed-by: Jarkko Sakkinen <[email protected]>
> Tested-by: Jarkko Sakkinen <[email protected]>
> ---
>
> V3: New in the series.
> V4: Resend.
> V5: Fix &buf.data -> buf.data in tpm1_continue_selftest()
>
> drivers/char/tpm/tpm.h | 9 ---------
> drivers/char/tpm/tpm1-cmd.c | 21 ++++++++++-----------
> 2 files changed, 10 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 2f06740f993d..7ada00f067f1 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 d418a27a75e0..6b04648f8184 100644
> --- a/drivers/char/tpm/tpm1-cmd.c
> +++ b/drivers/char/tpm/tpm1-cmd.c
> @@ -602,15 +602,8 @@ int tpm1_pcr_read(struct tpm_chip *chip, int 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
> + * 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
> @@ -618,12 +611,18 @@ 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;
> }
>


Reviewed-by: Nayna Jain <[email protected]>
Tested-by: Nayna Jain <[email protected]>


Thanks & Regards,
    - Nayna